View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.regionserver;
21  
22  import static org.apache.hadoop.hbase.regionserver.KeyValueScanFixture.scanFixture;
23  
24  import java.io.IOException;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.List;
28  import java.util.NavigableSet;
29  import java.util.TreeSet;
30  import java.util.concurrent.Callable;
31  import java.util.concurrent.ExecutionException;
32  import java.util.concurrent.Executors;
33  import java.util.concurrent.Future;
34  
35  import junit.framework.TestCase;
36  
37  import org.apache.hadoop.hbase.Cell;
38  import org.apache.hadoop.hbase.HBaseTestingUtility;
39  import org.apache.hadoop.hbase.HConstants;
40  import org.apache.hadoop.hbase.KeyValue;
41  import org.apache.hadoop.hbase.KeyValueTestUtil;
42  import org.apache.hadoop.hbase.MediumTests;
43  import org.apache.hadoop.hbase.client.HTable;
44  import org.apache.hadoop.hbase.client.Scan;
45  import org.apache.hadoop.hbase.util.Bytes;
46  import org.apache.hadoop.hbase.util.EnvironmentEdge;
47  import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper;
48  import org.apache.hadoop.hbase.util.Threads;
49  import org.junit.experimental.categories.Category;
50  
51  // Can't be small as it plays with EnvironmentEdgeManager
52  @Category(MediumTests.class)
53  public class TestStoreScanner extends TestCase {
54    private static final String CF_STR = "cf";
55    final byte [] CF = Bytes.toBytes(CF_STR);
56    private ScanInfo scanInfo = new ScanInfo(CF, 0, Integer.MAX_VALUE,
57        Long.MAX_VALUE, false, 0, KeyValue.COMPARATOR);
58    private ScanType scanType = ScanType.USER_SCAN;
59  
60    public void setUp() throws Exception {
61      super.setUp();
62    }
63  
64    /*
65     * Test utility for building a NavigableSet for scanners.
66     * @param strCols
67     * @return
68     */
69    NavigableSet<byte[]> getCols(String ...strCols) {
70      NavigableSet<byte[]> cols = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
71      for (String col : strCols) {
72        byte[] bytes = Bytes.toBytes(col);
73        cols.add(bytes);
74      }
75      return cols;
76    }
77  
78    public void testScanTimeRange() throws IOException {
79      String r1 = "R1";
80      // returns only 1 of these 2 even though same timestamp
81      KeyValue [] kvs = new KeyValue[] {
82          KeyValueTestUtil.create(r1, CF_STR, "a", 1, KeyValue.Type.Put, "dont-care"),
83          KeyValueTestUtil.create(r1, CF_STR, "a", 2, KeyValue.Type.Put, "dont-care"),
84          KeyValueTestUtil.create(r1, CF_STR, "a", 3, KeyValue.Type.Put, "dont-care"),
85          KeyValueTestUtil.create(r1, CF_STR, "a", 4, KeyValue.Type.Put, "dont-care"),
86          KeyValueTestUtil.create(r1, CF_STR, "a", 5, KeyValue.Type.Put, "dont-care"),
87      };
88      List<KeyValueScanner> scanners = Arrays.<KeyValueScanner>asList(
89          new KeyValueScanner[] {
90              new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
91      });
92      Scan scanSpec = new Scan(Bytes.toBytes(r1));
93      scanSpec.setTimeRange(0, 6);
94      scanSpec.setMaxVersions();
95      StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
96          getCols("a"), scanners);
97      List<Cell> results = new ArrayList<Cell>();
98      assertEquals(true, scan.next(results));
99      assertEquals(5, results.size());
100     assertEquals(kvs[kvs.length - 1], results.get(0));
101     // Scan limited TimeRange
102     scanSpec = new Scan(Bytes.toBytes(r1));
103     scanSpec.setTimeRange(1, 3);
104     scanSpec.setMaxVersions();
105     scan = new StoreScanner(scanSpec, scanInfo, scanType, getCols("a"),
106         scanners);
107     results = new ArrayList<Cell>();
108     assertEquals(true, scan.next(results));
109     assertEquals(2, results.size());
110     // Another range.
111     scanSpec = new Scan(Bytes.toBytes(r1));
112     scanSpec.setTimeRange(5, 10);
113     scanSpec.setMaxVersions();
114     scan = new StoreScanner(scanSpec, scanInfo, scanType, getCols("a"),
115         scanners);
116     results = new ArrayList<Cell>();
117     assertEquals(true, scan.next(results));
118     assertEquals(1, results.size());
119     // See how TimeRange and Versions interact.
120     // Another range.
121     scanSpec = new Scan(Bytes.toBytes(r1));
122     scanSpec.setTimeRange(0, 10);
123     scanSpec.setMaxVersions(3);
124     scan = new StoreScanner(scanSpec, scanInfo, scanType, getCols("a"),
125         scanners);
126     results = new ArrayList<Cell>();
127     assertEquals(true, scan.next(results));
128     assertEquals(3, results.size());
129   }
130 
131   public void testScanSameTimestamp() throws IOException {
132     // returns only 1 of these 2 even though same timestamp
133     KeyValue [] kvs = new KeyValue[] {
134         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
135         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
136     };
137     List<KeyValueScanner> scanners = Arrays.asList(
138         new KeyValueScanner[] {
139             new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
140         });
141 
142     Scan scanSpec = new Scan(Bytes.toBytes("R1"));
143     // this only uses maxVersions (default=1) and TimeRange (default=all)
144     StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
145         getCols("a"), scanners);
146 
147     List<Cell> results = new ArrayList<Cell>();
148     assertEquals(true, scan.next(results));
149     assertEquals(1, results.size());
150     assertEquals(kvs[0], results.get(0));
151   }
152 
153   /*
154    * Test test shows exactly how the matcher's return codes confuses the StoreScanner
155    * and prevent it from doing the right thing.  Seeking once, then nexting twice
156    * should return R1, then R2, but in this case it doesnt.
157    * TODO this comment makes no sense above. Appears to do the right thing.
158    * @throws IOException
159    */
160   public void testWontNextToNext() throws IOException {
161     // build the scan file:
162     KeyValue [] kvs = new KeyValue[] {
163         KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"),
164         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
165         KeyValueTestUtil.create("R2", "cf", "a", 1, KeyValue.Type.Put, "dont-care")
166     };
167     List<KeyValueScanner> scanners = scanFixture(kvs);
168 
169     Scan scanSpec = new Scan(Bytes.toBytes("R1"));
170     // this only uses maxVersions (default=1) and TimeRange (default=all)
171     StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
172         getCols("a"), scanners);
173 
174     List<Cell> results = new ArrayList<Cell>();
175     scan.next(results);
176     assertEquals(1, results.size());
177     assertEquals(kvs[0], results.get(0));
178     // should be ok...
179     // now scan _next_ again.
180     results.clear();
181     scan.next(results);
182     assertEquals(1, results.size());
183     assertEquals(kvs[2], results.get(0));
184 
185     results.clear();
186     scan.next(results);
187     assertEquals(0, results.size());
188 
189   }
190 
191 
192   public void testDeleteVersionSameTimestamp() throws IOException {
193     KeyValue [] kvs = new KeyValue [] {
194         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
195         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"),
196     };
197     List<KeyValueScanner> scanners = scanFixture(kvs);
198     Scan scanSpec = new Scan(Bytes.toBytes("R1"));
199     StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
200         getCols("a"), scanners);
201 
202     List<Cell> results = new ArrayList<Cell>();
203     assertFalse(scan.next(results));
204     assertEquals(0, results.size());
205   }
206 
207   /*
208    * Test the case where there is a delete row 'in front of' the next row, the scanner
209    * will move to the next row.
210    */
211   public void testDeletedRowThenGoodRow() throws IOException {
212     KeyValue [] kvs = new KeyValue [] {
213         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
214         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"),
215         KeyValueTestUtil.create("R2", "cf", "a", 20, KeyValue.Type.Put, "dont-care")
216     };
217     List<KeyValueScanner> scanners = scanFixture(kvs);
218     Scan scanSpec = new Scan(Bytes.toBytes("R1"));
219     StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
220         getCols("a"), scanners);
221 
222     List<Cell> results = new ArrayList<Cell>();
223     assertEquals(true, scan.next(results));
224     assertEquals(0, results.size());
225 
226     assertEquals(true, scan.next(results));
227     assertEquals(1, results.size());
228     assertEquals(kvs[2], results.get(0));
229 
230     assertEquals(false, scan.next(results));
231   }
232 
233   public void testDeleteVersionMaskingMultiplePuts() throws IOException {
234     long now = System.currentTimeMillis();
235     KeyValue [] kvs1 = new KeyValue[] {
236         KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
237         KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Delete, "dont-care")
238     };
239     KeyValue [] kvs2 = new KeyValue[] {
240         KeyValueTestUtil.create("R1", "cf", "a", now-500, KeyValue.Type.Put, "dont-care"),
241         KeyValueTestUtil.create("R1", "cf", "a", now-100, KeyValue.Type.Put, "dont-care"),
242         KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care")
243     };
244     List<KeyValueScanner> scanners = scanFixture(kvs1, kvs2);
245 
246     StoreScanner scan = new StoreScanner(new Scan(Bytes.toBytes("R1")),
247         scanInfo, scanType, getCols("a"), scanners);
248     List<Cell> results = new ArrayList<Cell>();
249     // the two put at ts=now will be masked by the 1 delete, and
250     // since the scan default returns 1 version we'll return the newest
251     // key, which is kvs[2], now-100.
252     assertEquals(true, scan.next(results));
253     assertEquals(1, results.size());
254     assertEquals(kvs2[1], results.get(0));
255   }
256   public void testDeleteVersionsMixedAndMultipleVersionReturn() throws IOException {
257     long now = System.currentTimeMillis();
258     KeyValue [] kvs1 = new KeyValue[] {
259         KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
260         KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Delete, "dont-care")
261     };
262     KeyValue [] kvs2 = new KeyValue[] {
263         KeyValueTestUtil.create("R1", "cf", "a", now-500, KeyValue.Type.Put, "dont-care"),
264         KeyValueTestUtil.create("R1", "cf", "a", now+500, KeyValue.Type.Put, "dont-care"),
265         KeyValueTestUtil.create("R1", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
266         KeyValueTestUtil.create("R2", "cf", "z", now, KeyValue.Type.Put, "dont-care")
267     };
268     List<KeyValueScanner> scanners = scanFixture(kvs1, kvs2);
269 
270     Scan scanSpec = new Scan(Bytes.toBytes("R1")).setMaxVersions(2);
271     StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
272         getCols("a"), scanners);
273     List<Cell> results = new ArrayList<Cell>();
274     assertEquals(true, scan.next(results));
275     assertEquals(2, results.size());
276     assertEquals(kvs2[1], results.get(0));
277     assertEquals(kvs2[0], results.get(1));
278   }
279 
280   public void testWildCardOneVersionScan() throws IOException {
281     KeyValue [] kvs = new KeyValue [] {
282         KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"),
283         KeyValueTestUtil.create("R1", "cf", "b", 1, KeyValue.Type.Put, "dont-care"),
284         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.DeleteColumn, "dont-care"),
285     };
286     List<KeyValueScanner> scanners = scanFixture(kvs);
287     StoreScanner scan = new StoreScanner(new Scan(Bytes.toBytes("R1")),
288         scanInfo, scanType, null, scanners);
289     List<Cell> results = new ArrayList<Cell>();
290     assertEquals(true, scan.next(results));
291     assertEquals(2, results.size());
292     assertEquals(kvs[0], results.get(0));
293     assertEquals(kvs[1], results.get(1));
294   }
295 
296   public void testWildCardScannerUnderDeletes() throws IOException {
297     KeyValue [] kvs = new KeyValue [] {
298         KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"), // inc
299         // orphaned delete column.
300         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.DeleteColumn, "dont-care"),
301         // column b
302         KeyValueTestUtil.create("R1", "cf", "b", 2, KeyValue.Type.Put, "dont-care"), // inc
303         KeyValueTestUtil.create("R1", "cf", "b", 1, KeyValue.Type.Put, "dont-care"), // inc
304         // column c
305         KeyValueTestUtil.create("R1", "cf", "c", 10, KeyValue.Type.Delete, "dont-care"),
306         KeyValueTestUtil.create("R1", "cf", "c", 10, KeyValue.Type.Put, "dont-care"), // no
307         KeyValueTestUtil.create("R1", "cf", "c", 9, KeyValue.Type.Put, "dont-care"),  // inc
308         // column d
309         KeyValueTestUtil.create("R1", "cf", "d", 11, KeyValue.Type.Put, "dont-care"), // inc
310         KeyValueTestUtil.create("R1", "cf", "d", 10, KeyValue.Type.DeleteColumn, "dont-care"),
311         KeyValueTestUtil.create("R1", "cf", "d", 9, KeyValue.Type.Put, "dont-care"),  // no
312         KeyValueTestUtil.create("R1", "cf", "d", 8, KeyValue.Type.Put, "dont-care"),  // no
313 
314     };
315     List<KeyValueScanner> scanners = scanFixture(kvs);
316     StoreScanner scan = new StoreScanner(new Scan().setMaxVersions(2),
317         scanInfo, scanType, null, scanners);
318     List<Cell> results = new ArrayList<Cell>();
319     assertEquals(true, scan.next(results));
320     assertEquals(5, results.size());
321     assertEquals(kvs[0], results.get(0));
322     assertEquals(kvs[2], results.get(1));
323     assertEquals(kvs[3], results.get(2));
324     assertEquals(kvs[6], results.get(3));
325     assertEquals(kvs[7], results.get(4));
326   }
327 
328   public void testDeleteFamily() throws IOException {
329     KeyValue [] kvs = new KeyValue[] {
330         KeyValueTestUtil.create("R1", "cf", "a", 100, KeyValue.Type.DeleteFamily, "dont-care"),
331         KeyValueTestUtil.create("R1", "cf", "b", 11, KeyValue.Type.Put, "dont-care"),
332         KeyValueTestUtil.create("R1", "cf", "c", 11, KeyValue.Type.Put, "dont-care"),
333         KeyValueTestUtil.create("R1", "cf", "d", 11, KeyValue.Type.Put, "dont-care"),
334         KeyValueTestUtil.create("R1", "cf", "e", 11, KeyValue.Type.Put, "dont-care"),
335         KeyValueTestUtil.create("R1", "cf", "e", 11, KeyValue.Type.DeleteColumn, "dont-care"),
336         KeyValueTestUtil.create("R1", "cf", "f", 11, KeyValue.Type.Put, "dont-care"),
337         KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Put, "dont-care"),
338         KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Delete, "dont-care"),
339         KeyValueTestUtil.create("R1", "cf", "h", 11, KeyValue.Type.Put, "dont-care"),
340         KeyValueTestUtil.create("R1", "cf", "i", 11, KeyValue.Type.Put, "dont-care"),
341         KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"),
342     };
343     List<KeyValueScanner> scanners = scanFixture(kvs);
344     StoreScanner scan = new StoreScanner(
345         new Scan().setMaxVersions(Integer.MAX_VALUE), scanInfo, scanType, null,
346         scanners);
347     List<Cell> results = new ArrayList<Cell>();
348     assertEquals(true, scan.next(results));
349     assertEquals(0, results.size());
350     assertEquals(true, scan.next(results));
351     assertEquals(1, results.size());
352     assertEquals(kvs[kvs.length-1], results.get(0));
353 
354     assertEquals(false, scan.next(results));
355   }
356 
357   public void testDeleteColumn() throws IOException {
358     KeyValue [] kvs = new KeyValue[] {
359         KeyValueTestUtil.create("R1", "cf", "a", 10, KeyValue.Type.DeleteColumn, "dont-care"),
360         KeyValueTestUtil.create("R1", "cf", "a", 9, KeyValue.Type.Delete, "dont-care"),
361         KeyValueTestUtil.create("R1", "cf", "a", 8, KeyValue.Type.Put, "dont-care"),
362         KeyValueTestUtil.create("R1", "cf", "b", 5, KeyValue.Type.Put, "dont-care")
363     };
364     List<KeyValueScanner> scanners = scanFixture(kvs);
365     StoreScanner scan = new StoreScanner(new Scan(), scanInfo, scanType, null,
366         scanners);
367     List<Cell> results = new ArrayList<Cell>();
368     assertEquals(true, scan.next(results));
369     assertEquals(1, results.size());
370     assertEquals(kvs[3], results.get(0));
371   }
372 
373   private static final  KeyValue [] kvs = new KeyValue[] {
374         KeyValueTestUtil.create("R1", "cf", "a", 11, KeyValue.Type.Put, "dont-care"),
375         KeyValueTestUtil.create("R1", "cf", "b", 11, KeyValue.Type.Put, "dont-care"),
376         KeyValueTestUtil.create("R1", "cf", "c", 11, KeyValue.Type.Put, "dont-care"),
377         KeyValueTestUtil.create("R1", "cf", "d", 11, KeyValue.Type.Put, "dont-care"),
378         KeyValueTestUtil.create("R1", "cf", "e", 11, KeyValue.Type.Put, "dont-care"),
379         KeyValueTestUtil.create("R1", "cf", "f", 11, KeyValue.Type.Put, "dont-care"),
380         KeyValueTestUtil.create("R1", "cf", "g", 11, KeyValue.Type.Put, "dont-care"),
381         KeyValueTestUtil.create("R1", "cf", "h", 11, KeyValue.Type.Put, "dont-care"),
382         KeyValueTestUtil.create("R1", "cf", "i", 11, KeyValue.Type.Put, "dont-care"),
383         KeyValueTestUtil.create("R2", "cf", "a", 11, KeyValue.Type.Put, "dont-care"),
384     };
385 
386   public void testSkipColumn() throws IOException {
387     List<KeyValueScanner> scanners = scanFixture(kvs);
388     StoreScanner scan = new StoreScanner(new Scan(), scanInfo, scanType,
389         getCols("a", "d"), scanners);
390 
391     List<Cell> results = new ArrayList<Cell>();
392     assertEquals(true, scan.next(results));
393     assertEquals(2, results.size());
394     assertEquals(kvs[0], results.get(0));
395     assertEquals(kvs[3], results.get(1));
396     results.clear();
397 
398     assertEquals(true, scan.next(results));
399     assertEquals(1, results.size());
400     assertEquals(kvs[kvs.length-1], results.get(0));
401 
402     results.clear();
403     assertEquals(false, scan.next(results));
404   }
405 
406   /*
407    * Test expiration of KeyValues in combination with a configured TTL for
408    * a column family (as should be triggered in a major compaction).
409    */
410   public void testWildCardTtlScan() throws IOException {
411     long now = System.currentTimeMillis();
412     KeyValue [] kvs = new KeyValue[] {
413         KeyValueTestUtil.create("R1", "cf", "a", now-1000, KeyValue.Type.Put, "dont-care"),
414         KeyValueTestUtil.create("R1", "cf", "b", now-10, KeyValue.Type.Put, "dont-care"),
415         KeyValueTestUtil.create("R1", "cf", "c", now-200, KeyValue.Type.Put, "dont-care"),
416         KeyValueTestUtil.create("R1", "cf", "d", now-10000, KeyValue.Type.Put, "dont-care"),
417         KeyValueTestUtil.create("R2", "cf", "a", now, KeyValue.Type.Put, "dont-care"),
418         KeyValueTestUtil.create("R2", "cf", "b", now-10, KeyValue.Type.Put, "dont-care"),
419         KeyValueTestUtil.create("R2", "cf", "c", now-200, KeyValue.Type.Put, "dont-care"),
420         KeyValueTestUtil.create("R2", "cf", "c", now-1000, KeyValue.Type.Put, "dont-care")
421     };
422     List<KeyValueScanner> scanners = scanFixture(kvs);
423     Scan scan = new Scan();
424     scan.setMaxVersions(1);
425     ScanInfo scanInfo = new ScanInfo(CF, 0, 1, 500, false, 0,
426         KeyValue.COMPARATOR);
427     ScanType scanType = ScanType.USER_SCAN;
428     StoreScanner scanner =
429       new StoreScanner(scan, scanInfo, scanType,
430           null, scanners);
431 
432     List<Cell> results = new ArrayList<Cell>();
433     assertEquals(true, scanner.next(results));
434     assertEquals(2, results.size());
435     assertEquals(kvs[1], results.get(0));
436     assertEquals(kvs[2], results.get(1));
437     results.clear();
438 
439     assertEquals(true, scanner.next(results));
440     assertEquals(3, results.size());
441     assertEquals(kvs[4], results.get(0));
442     assertEquals(kvs[5], results.get(1));
443     assertEquals(kvs[6], results.get(2));
444     results.clear();
445 
446     assertEquals(false, scanner.next(results));
447   }
448 
449   public void testScannerReseekDoesntNPE() throws Exception {
450     List<KeyValueScanner> scanners = scanFixture(kvs);
451     StoreScanner scan = new StoreScanner(new Scan(), scanInfo, scanType,
452         getCols("a", "d"), scanners);
453 
454     // Previously a updateReaders twice in a row would cause an NPE.  In test this would also
455     // normally cause an NPE because scan.store is null.  So as long as we get through these
456     // two calls we are good and the bug was quashed.
457 
458     scan.updateReaders();
459 
460     scan.updateReaders();
461 
462     scan.peek();
463   }
464 
465 
466   /**
467    * TODO this fails, since we don't handle deletions, etc, in peek
468    */
469   public void SKIP_testPeek() throws Exception {
470     KeyValue [] kvs = new KeyValue [] {
471         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"),
472         KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"),
473     };
474     List<KeyValueScanner> scanners = scanFixture(kvs);
475     Scan scanSpec = new Scan(Bytes.toBytes("R1"));
476     StoreScanner scan = new StoreScanner(scanSpec, scanInfo, scanType,
477         getCols("a"), scanners);
478     assertNull(scan.peek());
479   }
480 
481   /**
482    * Ensure that expired delete family markers don't override valid puts
483    */
484   public void testExpiredDeleteFamily() throws Exception {
485     long now = System.currentTimeMillis();
486     KeyValue [] kvs = new KeyValue[] {
487         new KeyValue(Bytes.toBytes("R1"), Bytes.toBytes("cf"), null, now-1000,
488             KeyValue.Type.DeleteFamily),
489         KeyValueTestUtil.create("R1", "cf", "a", now-10, KeyValue.Type.Put,
490             "dont-care"),
491     };
492     List<KeyValueScanner> scanners = scanFixture(kvs);
493     Scan scan = new Scan();
494     scan.setMaxVersions(1);
495     // scanner with ttl equal to 500
496     ScanInfo scanInfo = new ScanInfo(CF, 0, 1, 500, false, 0,
497         KeyValue.COMPARATOR);
498     ScanType scanType = ScanType.USER_SCAN;
499     StoreScanner scanner =
500         new StoreScanner(scan, scanInfo, scanType, null, scanners);
501 
502     List<Cell> results = new ArrayList<Cell>();
503     assertEquals(true, scanner.next(results));
504     assertEquals(1, results.size());
505     assertEquals(kvs[1], results.get(0));
506     results.clear();
507 
508     assertEquals(false, scanner.next(results));
509   }
510 
511   public void testDeleteMarkerLongevity() throws Exception {
512     try {
513       final long now = System.currentTimeMillis();
514       EnvironmentEdgeManagerTestHelper.injectEdge(new EnvironmentEdge() {
515         public long currentTimeMillis() {
516           return now;
517         }
518       });
519       KeyValue[] kvs = new KeyValue[]{
520         /*0*/ new KeyValue(Bytes.toBytes("R1"), Bytes.toBytes("cf"), null,
521         now - 100, KeyValue.Type.DeleteFamily), // live
522         /*1*/ new KeyValue(Bytes.toBytes("R1"), Bytes.toBytes("cf"), null,
523         now - 1000, KeyValue.Type.DeleteFamily), // expired
524         /*2*/ KeyValueTestUtil.create("R1", "cf", "a", now - 50,
525         KeyValue.Type.Put, "v3"), // live
526         /*3*/ KeyValueTestUtil.create("R1", "cf", "a", now - 55,
527         KeyValue.Type.Delete, "dontcare"), // live
528         /*4*/ KeyValueTestUtil.create("R1", "cf", "a", now - 55,
529         KeyValue.Type.Put, "deleted-version v2"), // deleted
530         /*5*/ KeyValueTestUtil.create("R1", "cf", "a", now - 60,
531         KeyValue.Type.Put, "v1"), // live
532         /*6*/ KeyValueTestUtil.create("R1", "cf", "a", now - 65,
533         KeyValue.Type.Put, "v0"), // max-version reached
534         /*7*/ KeyValueTestUtil.create("R1", "cf", "a",
535         now - 100, KeyValue.Type.DeleteColumn, "dont-care"), // max-version
536         /*8*/ KeyValueTestUtil.create("R1", "cf", "b", now - 600,
537         KeyValue.Type.DeleteColumn, "dont-care"), //expired
538         /*9*/ KeyValueTestUtil.create("R1", "cf", "b", now - 70,
539         KeyValue.Type.Put, "v2"), //live
540         /*10*/ KeyValueTestUtil.create("R1", "cf", "b", now - 750,
541         KeyValue.Type.Put, "v1"), //expired
542         /*11*/ KeyValueTestUtil.create("R1", "cf", "c", now - 500,
543         KeyValue.Type.Delete, "dontcare"), //expired
544         /*12*/ KeyValueTestUtil.create("R1", "cf", "c", now - 600,
545         KeyValue.Type.Put, "v1"), //expired
546         /*13*/ KeyValueTestUtil.create("R1", "cf", "c", now - 1000,
547         KeyValue.Type.Delete, "dontcare"), //expired
548         /*14*/ KeyValueTestUtil.create("R1", "cf", "d", now - 60,
549         KeyValue.Type.Put, "expired put"), //live
550         /*15*/ KeyValueTestUtil.create("R1", "cf", "d", now - 100,
551         KeyValue.Type.Delete, "not-expired delete"), //live
552       };
553       List<KeyValueScanner> scanners = scanFixture(kvs);
554       Scan scan = new Scan();
555       scan.setMaxVersions(2);
556       ScanInfo scanInfo = new ScanInfo(Bytes.toBytes("cf"),
557         0 /* minVersions */,
558         2 /* maxVersions */, 500 /* ttl */,
559         false /* keepDeletedCells */,
560         200, /* timeToPurgeDeletes */
561         KeyValue.COMPARATOR);
562       StoreScanner scanner =
563         new StoreScanner(scan, scanInfo,
564           ScanType.COMPACT_DROP_DELETES, null, scanners,
565           HConstants.OLDEST_TIMESTAMP);
566       List<Cell> results = new ArrayList<Cell>();
567       results = new ArrayList<Cell>();
568       assertEquals(true, scanner.next(results));
569       assertEquals(kvs[0], results.get(0));
570       assertEquals(kvs[2], results.get(1));
571       assertEquals(kvs[3], results.get(2));
572       assertEquals(kvs[5], results.get(3));
573       assertEquals(kvs[9], results.get(4));
574       assertEquals(kvs[14], results.get(5));
575       assertEquals(kvs[15], results.get(6));
576       assertEquals(7, results.size());
577       scanner.close();
578     }finally{
579     EnvironmentEdgeManagerTestHelper.reset();
580     }
581   }
582 
583 }
584