View Javadoc

1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.regionserver;
22  
23  import org.apache.hadoop.hbase.HConstants;
24  import org.apache.hadoop.hbase.KeyValue;
25  import org.apache.hadoop.hbase.io.hfile.HFile;
26  
27  import java.io.IOException;
28  import java.util.List;
29  
30  /**
31   * A scanner that does a minor compaction at the same time.  Doesn't need to
32   * implement ChangedReadersObserver, since it doesn't scan memstore, only store files
33   * and optionally the memstore-snapshot.
34   */
35  public class MinorCompactingStoreScanner implements KeyValueScanner, InternalScanner {
36    private KeyValueHeap heap;
37    private KeyValue.KVComparator comparator;
38  
39    MinorCompactingStoreScanner(Store store, List<? extends KeyValueScanner> scanners)
40        throws IOException {
41      comparator = store.comparator;
42      KeyValue firstKv = KeyValue.createFirstOnRow(HConstants.EMPTY_START_ROW);
43      for (KeyValueScanner scanner : scanners ) {
44        scanner.seek(firstKv);
45      }
46      heap = new KeyValueHeap(scanners, store.comparator);
47    }
48  
49    MinorCompactingStoreScanner(String cfName, KeyValue.KVComparator comparator,
50                                List<? extends KeyValueScanner> scanners)
51        throws IOException {
52      this.comparator = comparator;
53  
54      KeyValue firstKv = KeyValue.createFirstOnRow(HConstants.EMPTY_START_ROW);
55      for (KeyValueScanner scanner : scanners ) {
56        scanner.seek(firstKv);
57      }
58  
59      heap = new KeyValueHeap(scanners, comparator);
60    }
61  
62    public KeyValue peek() {
63      return heap.peek();
64    }
65  
66    public KeyValue next() throws IOException {
67      return heap.next();
68    }
69  
70    @Override
71    public boolean seek(KeyValue key) {
72      // cant seek.
73      throw new UnsupportedOperationException("Can't seek a MinorCompactingStoreScanner");
74    }
75  
76    /**
77     * High performance merge scan.
78     * @param writer
79     * @return True if more.
80     * @throws IOException
81     */
82    public boolean next(StoreFile.Writer writer) throws IOException {
83      KeyValue row = heap.peek();
84      if (row == null) {
85        close();
86        return false;
87      }
88      KeyValue kv;
89      while ((kv = heap.peek()) != null) {
90        // check to see if this is a different row
91        if (comparator.compareRows(row, kv) != 0) {
92          // reached next row
93          return true;
94        }
95        writer.append(heap.next());
96      }
97      close();
98      return false;
99    }
100 
101   @Override
102   public boolean next(List<KeyValue> results) throws IOException {
103     KeyValue row = heap.peek();
104     if (row == null) {
105       close();
106       return false;
107     }
108     KeyValue kv;
109     while ((kv = heap.peek()) != null) {
110       // check to see if this is a different row
111       if (comparator.compareRows(row, kv) != 0) {
112         // reached next row
113         return true;
114       }
115       results.add(heap.next());
116     }
117     close();
118     return false;
119   }
120 
121   @Override
122   public boolean next(List<KeyValue> results, int limit) throws IOException {
123     // should not use limits with minor compacting store scanner
124     return next(results);
125   }
126 
127   public void close() {
128     heap.close();
129   }
130 }