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