diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompositeImmutableSegment.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompositeImmutableSegment.java index 1fd2f23a3a0..dcfaf812d4b 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompositeImmutableSegment.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompositeImmutableSegment.java @@ -279,4 +279,13 @@ public class CompositeImmutableSegment extends ImmutableSegment { } return sb.toString(); } + + @Override + List getSnapshotScanners() { + List list = new ArrayList<>(this.segments.size()); + for (ImmutableSegment segment: this.segments) { + list.add(new SnapshotSegmentScanner(segment)); + } + return list; + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ImmutableSegment.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ImmutableSegment.java index b781aab804c..8c426bc655a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ImmutableSegment.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ImmutableSegment.java @@ -84,4 +84,8 @@ public abstract class ImmutableSegment extends Segment { res += "Num uniques "+getNumUniqueKeys()+"; "; return res; } + + List getSnapshotScanners() { + return Collections.singletonList(new SnapshotSegmentScanner(this)); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreSnapshot.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreSnapshot.java index f74722483f7..3b3482898cd 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreSnapshot.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MemStoreSnapshot.java @@ -40,7 +40,7 @@ public class MemStoreSnapshot implements Closeable { this.cellsCount = snapshot.getCellsCount(); this.memStoreSize = snapshot.getMemStoreSize(); this.timeRangeTracker = snapshot.getTimeRangeTracker(); - this.scanners = snapshot.getScanners(Long.MAX_VALUE); + this.scanners = snapshot.getSnapshotScanners(); this.tagsPresent = snapshot.isTagsPresent(); } @@ -95,5 +95,4 @@ public class MemStoreSnapshot implements Closeable { } } } - } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SnapshotSegmentScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SnapshotSegmentScanner.java new file mode 100644 index 00000000000..87be2e4031d --- /dev/null +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/SnapshotSegmentScanner.java @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.regionserver; + +import java.util.Iterator; + +import org.apache.hadoop.hbase.Cell; +import org.apache.yetus.audience.InterfaceAudience; + + +/** + * A basic SegmentScanner used against an ImmutableScanner snapshot + * Used flushing where we do a single pass, no reverse scanning or + * inserts happening. Its a dumbed-down Scanner that can go fast. + * Like {@link org.apache.hadoop.hbase.util.CollectionBackedScanner} + * (but making it know about Segments was onerous). + */ +@InterfaceAudience.Private +public class SnapshotSegmentScanner extends NonReversedNonLazyKeyValueScanner { + private final ImmutableSegment segment; + private Iterator iter; + private Cell current; + + public SnapshotSegmentScanner(ImmutableSegment segment) { + this.segment = segment; + this.segment.incScannerCount(); + this.iter = createIterator(this.segment); + if (this.iter.hasNext()){ + this.current = this.iter.next(); + } + } + + private static Iterator createIterator(Segment segment) { + return segment.getCellSet().iterator(); + } + + @Override + public Cell peek() { + return current; + } + + @Override + public Cell next() { + Cell oldCurrent = current; + if(iter.hasNext()){ + current = iter.next(); + } else { + current = null; + } + return oldCurrent; + } + + @Override + public boolean seek(Cell seekCell) { + // restart iterator + this.iter = createIterator(this.segment); + return reseek(seekCell); + } + + @Override + public boolean reseek(Cell seekCell) { + while (this.iter.hasNext()){ + Cell next = this.iter.next(); + int ret = this.segment.getComparator().compare(next, seekCell); + if (ret >= 0) { + this.current = next; + return true; + } + } + return false; + } + + /** + * @see KeyValueScanner#getScannerOrder() + */ + @Override + public long getScannerOrder() { + return 0; + } + + @Override + public void close() { + this.segment.decScannerCount(); + } +}