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.util;
020
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.Iterator;
024import java.util.List;
025import java.util.SortedSet;
026
027import org.apache.yetus.audience.InterfaceAudience;
028import org.apache.hadoop.hbase.Cell;
029import org.apache.hadoop.hbase.CellComparator;
030import org.apache.hadoop.hbase.regionserver.NonReversedNonLazyKeyValueScanner;
031
032/**
033 * Utility scanner that wraps a sortable collection and serves as a KeyValueScanner.
034 */
035@InterfaceAudience.Private
036public class CollectionBackedScanner extends NonReversedNonLazyKeyValueScanner {
037  final private Iterable<Cell> data;
038  final CellComparator comparator;
039  private Iterator<Cell> iter;
040  private Cell current;
041
042  public CollectionBackedScanner(SortedSet<Cell> set) {
043    this(set, CellComparator.getInstance());
044  }
045
046  public CollectionBackedScanner(SortedSet<Cell> set,
047      CellComparator comparator) {
048    this.comparator = comparator;
049    data = set;
050    init();
051  }
052
053  public CollectionBackedScanner(List<Cell> list) {
054    this(list, CellComparator.getInstance());
055  }
056
057  public CollectionBackedScanner(List<Cell> list,
058      CellComparator comparator) {
059    Collections.sort(list, comparator);
060    this.comparator = comparator;
061    data = list;
062    init();
063  }
064
065  public CollectionBackedScanner(CellComparator comparator,
066      Cell... array) {
067    this.comparator = comparator;
068
069    List<Cell> tmp = new ArrayList<>(array.length);
070    Collections.addAll(tmp, array);
071    Collections.sort(tmp, comparator);
072    data = tmp;
073    init();
074  }
075
076  private void init() {
077    iter = data.iterator();
078    if(iter.hasNext()){
079      current = iter.next();
080    }
081  }
082
083  @Override
084  public Cell peek() {
085    return current;
086  }
087
088  @Override
089  public Cell next() {
090    Cell oldCurrent = current;
091    if(iter.hasNext()){
092      current = iter.next();
093    } else {
094      current = null;
095    }
096    return oldCurrent;
097  }
098
099  @Override
100  public boolean seek(Cell seekCell) {
101    // restart iterator
102    iter = data.iterator();
103    return reseek(seekCell);
104  }
105
106  @Override
107  public boolean reseek(Cell seekCell) {
108    while(iter.hasNext()){
109      Cell next = iter.next();
110      int ret = comparator.compare(next, seekCell);
111      if(ret >= 0){
112        current = next;
113        return true;
114      }
115    }
116    return false;
117  }
118
119
120  @Override
121  public void close() {
122    // do nothing
123  }
124}