001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver;
019
020import java.util.ArrayList;
021import java.util.Iterator;
022import java.util.List;
023import java.util.SortedSet;
024import org.apache.hadoop.hbase.Cell;
025import org.apache.hadoop.hbase.CellComparator;
026import org.apache.hadoop.hbase.io.TimeRange;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.slf4j.Logger;
029
030/**
031 * The CompositeImmutableSegments is created as a collection of ImmutableSegments and supports the
032 * interface of a single ImmutableSegments. The CompositeImmutableSegments is planned to be used
033 * only as a snapshot, thus only relevant interfaces are supported
034 */
035@InterfaceAudience.Private
036public class CompositeImmutableSegment extends ImmutableSegment {
037
038  private final List<ImmutableSegment> segments;
039  private long keySize = 0;
040
041  public CompositeImmutableSegment(CellComparator comparator, List<ImmutableSegment> segments) {
042    super(comparator, segments);
043    this.segments = segments;
044    for (ImmutableSegment s : segments) {
045      this.timeRangeTracker.includeTimestamp(s.getTimeRangeTracker().getMax());
046      this.timeRangeTracker.includeTimestamp(s.getTimeRangeTracker().getMin());
047      this.keySize += s.getDataSize();
048    }
049  }
050
051  @Override
052  public List<Segment> getAllSegments() {
053    return new ArrayList<>(segments);
054  }
055
056  @Override
057  public int getNumOfSegments() {
058    return segments.size();
059  }
060
061  /** Returns whether the segment has any cells */
062  @Override
063  public boolean isEmpty() {
064    for (ImmutableSegment s : segments) {
065      if (!s.isEmpty()) return false;
066    }
067    return true;
068  }
069
070  /** Returns number of cells in segment */
071  @Override
072  public int getCellsCount() {
073    int result = 0;
074    for (ImmutableSegment s : segments) {
075      result += s.getCellsCount();
076    }
077    return result;
078  }
079
080  /**
081   * Closing a segment before it is being discarded
082   */
083  @Override
084  public void close() {
085    for (ImmutableSegment s : segments) {
086      s.close();
087    }
088  }
089
090  /**
091   * If the segment has a memory allocator the cell is being cloned to this space, and returned;
092   * otherwise the given cell is returned
093   * @return either the given cell or its clone
094   */
095  @Override
096  public Cell maybeCloneWithAllocator(Cell cell, boolean forceCloneOfBigCell) {
097    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
098  }
099
100  @Override
101  public boolean shouldSeek(TimeRange tr, long oldestUnexpiredTS) {
102    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
103  }
104
105  /**
106   * Creates the scanner for the given read point
107   * @return a scanner for the given read point
108   */
109  @Override
110  public KeyValueScanner getScanner(long readPoint) {
111    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
112  }
113
114  @Override
115  public List<KeyValueScanner> getScanners(long readPoint) {
116    List<KeyValueScanner> list = new ArrayList<>(segments.size());
117    AbstractMemStore.addToScanners(segments, readPoint, list);
118    return list;
119  }
120
121  @Override
122  public boolean isTagsPresent() {
123    for (ImmutableSegment s : segments) {
124      if (s.isTagsPresent()) return true;
125    }
126    return false;
127  }
128
129  @Override
130  public void incScannerCount() {
131    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
132  }
133
134  @Override
135  public void decScannerCount() {
136    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
137  }
138
139  /**
140   * Setting the CellSet of the segment - used only for flat immutable segment for setting immutable
141   * CellSet after its creation in immutable segment constructor
142   * @return this object
143   */
144  @Override
145  protected CompositeImmutableSegment setCellSet(CellSet cellSetOld, CellSet cellSetNew) {
146    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
147  }
148
149  @Override
150  protected long indexEntrySize() {
151    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
152  }
153
154  @Override
155  protected boolean canBeFlattened() {
156    return false;
157  }
158
159  /** Returns Sum of all cell sizes. */
160  @Override
161  public long getDataSize() {
162    return this.keySize;
163  }
164
165  /** Returns The heap size of this segment. */
166  @Override
167  public long getHeapSize() {
168    long result = 0;
169    for (ImmutableSegment s : segments) {
170      result += s.getHeapSize();
171    }
172    return result;
173  }
174
175  /**
176   * Updates the heap size counter of the segment by the given delta
177   */
178  @Override
179  public long incMemStoreSize(long delta, long heapOverhead, long offHeapOverhead, int cellsCount) {
180    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
181  }
182
183  @Override
184  public long getMinSequenceId() {
185    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
186  }
187
188  @Override
189  public TimeRangeTracker getTimeRangeTracker() {
190    return this.timeRangeTracker;
191  }
192
193  // *** Methods for SegmentsScanner
194  @Override
195  public Cell last() {
196    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
197  }
198
199  @Override
200  public Iterator<Cell> iterator() {
201    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
202  }
203
204  @Override
205  public SortedSet<Cell> headSet(Cell firstKeyOnRow) {
206    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
207  }
208
209  @Override
210  public int compare(Cell left, Cell right) {
211    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
212  }
213
214  @Override
215  public int compareRows(Cell left, Cell right) {
216    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
217  }
218
219  /** Returns a set of all cells in the segment */
220  @Override
221  protected CellSet getCellSet() {
222    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
223  }
224
225  @Override
226  protected void internalAdd(Cell cell, boolean mslabUsed, MemStoreSizing memstoreSizing,
227    boolean sizeAddedPreOperation) {
228    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
229  }
230
231  @Override
232  protected void updateMetaInfo(Cell cellToAdd, boolean succ, boolean mslabUsed,
233    MemStoreSizing memstoreSizing, boolean sizeAddedPreOperation) {
234    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
235  }
236
237  /**
238   * Returns a subset of the segment cell set, which starts with the given cell
239   * @param firstCell a cell in the segment
240   * @return a subset of the segment cell set, which starts with the given cell
241   */
242  @Override
243  protected SortedSet<Cell> tailSet(Cell firstCell) {
244    throw new IllegalStateException("Not supported by CompositeImmutableScanner");
245  }
246
247  // Debug methods
248  /**
249   * Dumps all cells of the segment into the given log
250   */
251  @Override
252  void dump(Logger log) {
253    for (ImmutableSegment s : segments) {
254      s.dump(log);
255    }
256  }
257
258  @Override
259  public String toString() {
260    StringBuilder sb =
261      new StringBuilder("This is CompositeImmutableSegment and those are its segments:: ");
262    for (ImmutableSegment s : segments) {
263      sb.append(s.toString());
264    }
265    return sb.toString();
266  }
267
268  @Override
269  List<KeyValueScanner> getSnapshotScanners() {
270    List<KeyValueScanner> list = new ArrayList<>(this.segments.size());
271    for (ImmutableSegment segment : this.segments) {
272      list.add(new SnapshotSegmentScanner(segment));
273    }
274    return list;
275  }
276}