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 */
019
020package org.apache.hadoop.hbase.regionserver;
021
022import org.apache.hadoop.hbase.Cell;
023import org.apache.hadoop.hbase.CellComparator;
024import org.apache.yetus.audience.InterfaceAudience;
025
026import java.io.IOException;
027import java.util.ArrayList;
028import java.util.List;
029
030/**
031 * The MemStoreMergerSegmentsIterator extends MemStoreSegmentsIterator
032 * and performs the scan for simple merge operation meaning it is NOT based on SQM
033 */
034@InterfaceAudience.Private
035public class MemStoreMergerSegmentsIterator extends MemStoreSegmentsIterator {
036
037  // heap of scanners, lazily initialized
038  private KeyValueHeap heap = null;
039  // remember the initial version of the scanners list
040  List<KeyValueScanner> scanners  = new ArrayList<KeyValueScanner>();
041
042  private boolean closed = false;
043
044  // C-tor
045  public MemStoreMergerSegmentsIterator(List<ImmutableSegment> segments, CellComparator comparator,
046      int compactionKVMax) throws IOException {
047    super(compactionKVMax);
048    // create the list of scanners to traverse over all the data
049    // no dirty reads here as these are immutable segments
050    AbstractMemStore.addToScanners(segments, Long.MAX_VALUE, scanners);
051    heap = new KeyValueHeap(scanners, comparator);
052  }
053
054  @Override
055  public boolean hasNext() {
056    if (closed) {
057      return false;
058    }
059    if (this.heap != null) {
060      return (this.heap.peek() != null);
061    }
062    // Doing this way in case some test cases tries to peek directly
063    return false;
064  }
065
066  @Override
067  public Cell next()  {
068    try {                 // try to get next
069      if (!closed && heap != null) {
070        return heap.next();
071      }
072    } catch (IOException ie) {
073      throw new IllegalStateException(ie);
074    }
075    return null;
076  }
077
078  @Override
079  public void close() {
080    if (closed) {
081      return;
082    }
083    // Ensuring that all the segment scanners are closed
084    if (heap != null) {
085      heap.close();
086      // It is safe to do close as no new calls will be made to this scanner.
087      heap = null;
088    } else {
089      for (KeyValueScanner scanner : scanners) {
090        scanner.close();
091      }
092    }
093    closed = true;
094  }
095
096  @Override
097  public void remove() {
098    throw new UnsupportedOperationException();
099  }
100}