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