~ubuntu-branches/ubuntu/precise/hbase/precise

« back to all changes in this revision

Viewing changes to src/test/org/apache/hadoop/hbase/regionserver/TestHRegion.java

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Koch
  • Date: 2010-05-06 14:20:42 UTC
  • Revision ID: james.westby@ubuntu.com-20100506142042-r3hlvgxdcpb8tynl
Tags: upstream-0.20.4+dfsg1
ImportĀ upstreamĀ versionĀ 0.20.4+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright 2007 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
package org.apache.hadoop.hbase.regionserver;
 
21
 
 
22
import java.io.IOException;
 
23
import java.util.ArrayList;
 
24
import java.util.List;
 
25
import java.util.TreeMap;
 
26
import java.util.Arrays;
 
27
import java.util.concurrent.atomic.AtomicBoolean;
 
28
import java.util.concurrent.atomic.AtomicInteger;
 
29
 
 
30
import junit.framework.Assert;
 
31
 
 
32
import org.apache.commons.logging.Log;
 
33
import org.apache.commons.logging.LogFactory;
 
34
import org.apache.hadoop.fs.Path;
 
35
import org.apache.hadoop.hbase.HBaseConfiguration;
 
36
import org.apache.hadoop.hbase.HBaseTestCase;
 
37
import org.apache.hadoop.hbase.HColumnDescriptor;
 
38
import org.apache.hadoop.hbase.HConstants;
 
39
import org.apache.hadoop.hbase.HRegionInfo;
 
40
import org.apache.hadoop.hbase.HTableDescriptor;
 
41
import org.apache.hadoop.hbase.KeyValue;
 
42
import org.apache.hadoop.hbase.client.Delete;
 
43
import org.apache.hadoop.hbase.client.Get;
 
44
import org.apache.hadoop.hbase.client.Put;
 
45
import org.apache.hadoop.hbase.client.Result;
 
46
import org.apache.hadoop.hbase.client.Scan;
 
47
import org.apache.hadoop.hbase.filter.BinaryComparator;
 
48
import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
 
49
import org.apache.hadoop.hbase.filter.CompareFilter;
 
50
import org.apache.hadoop.hbase.filter.Filter;
 
51
import org.apache.hadoop.hbase.filter.FilterList;
 
52
import org.apache.hadoop.hbase.filter.PrefixFilter;
 
53
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
 
54
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 
55
import org.apache.hadoop.hbase.filter.RowFilter;
 
56
import org.apache.hadoop.hbase.regionserver.HRegion.RegionScanner;
 
57
import org.apache.hadoop.hbase.util.Bytes;
 
58
 
 
59
/**
 
60
 * Basic stand-alone testing of HRegion.
 
61
 * 
 
62
 * A lot of the meta information for an HRegion now lives inside other
 
63
 * HRegions or in the HBaseMaster, so only basic testing is possible.
 
64
 */
 
65
public class TestHRegion extends HBaseTestCase {
 
66
  static final Log LOG = LogFactory.getLog(TestHRegion.class);
 
67
 
 
68
  HRegion region = null;
 
69
  private final String DIR = "test/build/data/TestHRegion/";
 
70
  
 
71
  private final int MAX_VERSIONS = 2;
 
72
 
 
73
  // Test names
 
74
  protected final byte[] tableName = Bytes.toBytes("testtable");;
 
75
  protected final byte[] qual1 = Bytes.toBytes("qual1");
 
76
  protected final byte[] qual2 = Bytes.toBytes("qual2");
 
77
  protected final byte[] qual3 = Bytes.toBytes("qual3");
 
78
  protected final byte[] value1 = Bytes.toBytes("value1");
 
79
  protected final byte[] value2 = Bytes.toBytes("value2");
 
80
  protected final byte [] row = Bytes.toBytes("rowA");
 
81
 
 
82
  /**
 
83
   * @see org.apache.hadoop.hbase.HBaseTestCase#setUp()
 
84
   */
 
85
  @Override
 
86
  protected void setUp() throws Exception {
 
87
    super.setUp();
 
88
  }
 
89
 
 
90
  //////////////////////////////////////////////////////////////////////////////
 
91
  // New tests that doesn't spin up a mini cluster but rather just test the 
 
92
  // individual code pieces in the HRegion. Putting files locally in
 
93
  // /tmp/testtable
 
94
  //////////////////////////////////////////////////////////////////////////////
 
95
 
 
96
  public void testGetWhileRegionClose() throws IOException {
 
97
    HBaseConfiguration hc = initSplit();
 
98
    int numRows = 100;
 
99
    byte [][] families = {fam1, fam2, fam3};
 
100
    
 
101
    //Setting up region
 
102
    String method = this.getName();
 
103
    initHRegion(tableName, method, hc, families);
 
104
 
 
105
    // Put data in region
 
106
    final int startRow = 100;
 
107
    putData(startRow, numRows, qual1, families);
 
108
    putData(startRow, numRows, qual2, families);
 
109
    putData(startRow, numRows, qual3, families);
 
110
    // this.region.flushcache();
 
111
    final AtomicBoolean done = new AtomicBoolean(false);
 
112
    final AtomicInteger gets = new AtomicInteger(0);
 
113
    GetTillDoneOrException [] threads = new GetTillDoneOrException[10];
 
114
    try {
 
115
      // Set ten threads running concurrently getting from the region.
 
116
      for (int i = 0; i < threads.length / 2; i++) {
 
117
        threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow),
 
118
          done, gets);
 
119
        threads[i].setDaemon(true);
 
120
        threads[i].start();
 
121
      }
 
122
      // Artificially make the condition by setting closing flag explicitly.
 
123
      // I can't make the issue happen with a call to region.close().
 
124
      this.region.closing.set(true);
 
125
      for (int i = threads.length / 2; i < threads.length; i++) {
 
126
        threads[i] = new GetTillDoneOrException(i, Bytes.toBytes("" + startRow),
 
127
          done, gets);
 
128
        threads[i].setDaemon(true);
 
129
        threads[i].start();
 
130
      }
 
131
    } finally {
 
132
      if (this.region != null) {
 
133
        this.region.close();
 
134
        this.region.getLog().closeAndDelete();
 
135
      }
 
136
    }
 
137
    done.set(true);
 
138
    for (GetTillDoneOrException t: threads) {
 
139
      try {
 
140
        t.join();
 
141
      } catch (InterruptedException e) {
 
142
        e.printStackTrace();
 
143
      }
 
144
      if (t.e != null) {
 
145
        LOG.info("Exception=" + t.e);
 
146
        assertFalse("Found a NPE in " + t.getName(),
 
147
          t.e instanceof NullPointerException);
 
148
      }
 
149
    }
 
150
  }
 
151
 
 
152
  /*
 
153
   * Thread that does get on single row until 'done' flag is flipped.  If an
 
154
   * exception causes us to fail, it records it.
 
155
   */
 
156
  class GetTillDoneOrException extends Thread {
 
157
    private final Get g;
 
158
    private final AtomicBoolean done;
 
159
    private final AtomicInteger count;
 
160
    private Exception e;
 
161
 
 
162
    GetTillDoneOrException(final int i, final byte[] r, final AtomicBoolean d,
 
163
        final AtomicInteger c) {
 
164
      super("getter." + i);
 
165
      this.g = new Get(r);
 
166
      this.done = d;
 
167
      this.count = c;
 
168
    }
 
169
 
 
170
    @Override
 
171
    public void run() {
 
172
      while (!this.done.get()) {
 
173
        try {
 
174
          assertTrue(region.get(g, null).size() > 0);
 
175
          this.count.incrementAndGet();
 
176
        } catch (Exception e) {
 
177
          this.e = e;
 
178
          break;
 
179
        }
 
180
      }
 
181
    }
 
182
  }
 
183
 
 
184
  /*
 
185
   * An involved filter test.  Has multiple column families and deletes in mix.
 
186
   */
 
187
  public void testWeirdCacheBehaviour() throws Exception {
 
188
    byte[] TABLE = Bytes.toBytes("testWeirdCacheBehaviour");
 
189
    byte[][] FAMILIES = new byte[][] { Bytes.toBytes("trans-blob"),
 
190
        Bytes.toBytes("trans-type"), Bytes.toBytes("trans-date"),
 
191
        Bytes.toBytes("trans-tags"), Bytes.toBytes("trans-group") };
 
192
    initHRegion(TABLE, getName(), FAMILIES);
 
193
    String value = "this is the value";
 
194
    String value2 = "this is some other value";
 
195
    String keyPrefix1 = "prefix1"; // UUID.randomUUID().toString();
 
196
    String keyPrefix2 = "prefix2"; // UUID.randomUUID().toString();
 
197
    String keyPrefix3 = "prefix3"; // UUID.randomUUID().toString();
 
198
    putRows(this.region, 3, value, keyPrefix1);
 
199
    putRows(this.region, 3, value, keyPrefix2);
 
200
    putRows(this.region, 3, value, keyPrefix3);
 
201
    // this.region.flushCommits();
 
202
    putRows(this.region, 3, value2, keyPrefix1);
 
203
    putRows(this.region, 3, value2, keyPrefix2);
 
204
    putRows(this.region, 3, value2, keyPrefix3);
 
205
    System.out.println("Checking values for key: " + keyPrefix1);
 
206
    assertEquals("Got back incorrect number of rows from scan", 3,
 
207
      getNumberOfRows(keyPrefix1, value2, this.region));
 
208
    System.out.println("Checking values for key: " + keyPrefix2);
 
209
    assertEquals("Got back incorrect number of rows from scan", 3,
 
210
      getNumberOfRows(keyPrefix2, value2, this.region));
 
211
    System.out.println("Checking values for key: " + keyPrefix3);
 
212
    assertEquals("Got back incorrect number of rows from scan", 3,
 
213
      getNumberOfRows(keyPrefix3, value2, this.region));
 
214
    deleteColumns(this.region, value2, keyPrefix1);
 
215
    deleteColumns(this.region, value2, keyPrefix2);
 
216
    deleteColumns(this.region, value2, keyPrefix3);
 
217
    System.out.println("Starting important checks.....");
 
218
    assertEquals("Got back incorrect number of rows from scan: " + keyPrefix1,
 
219
      0, getNumberOfRows(keyPrefix1, value2, this.region));
 
220
    assertEquals("Got back incorrect number of rows from scan: " + keyPrefix2,
 
221
      0, getNumberOfRows(keyPrefix2, value2, this.region));
 
222
    assertEquals("Got back incorrect number of rows from scan: " + keyPrefix3,
 
223
      0, getNumberOfRows(keyPrefix3, value2, this.region));
 
224
  }
 
225
 
 
226
  private void deleteColumns(HRegion r, String value, String keyPrefix)
 
227
  throws IOException {
 
228
    InternalScanner scanner = buildScanner(keyPrefix, value, r);
 
229
    int count = 0;
 
230
    boolean more = false;
 
231
    List<KeyValue> results = new ArrayList<KeyValue>();
 
232
    do {
 
233
      more = scanner.next(results);
 
234
      if (results != null && !results.isEmpty())
 
235
        count++;
 
236
      else
 
237
        break;
 
238
      Delete delete = new Delete(results.get(0).getRow());
 
239
      delete.deleteColumn(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"));
 
240
      r.delete(delete, null, false);
 
241
      results.clear();
 
242
    } while (more);
 
243
    assertEquals("Did not perform correct number of deletes", 3, count);
 
244
  }
 
245
 
 
246
  private int getNumberOfRows(String keyPrefix, String value, HRegion r) throws Exception {
 
247
    InternalScanner resultScanner = buildScanner(keyPrefix, value, r);
 
248
    int numberOfResults = 0;
 
249
    List<KeyValue> results = new ArrayList<KeyValue>();
 
250
    boolean more = false;
 
251
    do {
 
252
      more = resultScanner.next(results);
 
253
      if (results != null && !results.isEmpty()) numberOfResults++;
 
254
      else break;
 
255
      for (KeyValue kv: results) {
 
256
        System.out.println("kv=" + kv.toString() + ", " + Bytes.toString(kv.getValue()));
 
257
      }
 
258
      results.clear();
 
259
    } while(more);
 
260
    return numberOfResults;
 
261
  }
 
262
 
 
263
  private InternalScanner buildScanner(String keyPrefix, String value, HRegion r)
 
264
  throws IOException {
 
265
    // Defaults FilterList.Operator.MUST_PASS_ALL.
 
266
    FilterList allFilters = new FilterList();
 
267
    allFilters.addFilter(new PrefixFilter(Bytes.toBytes(keyPrefix)));
 
268
    // Only return rows where this column value exists in the row.
 
269
    SingleColumnValueFilter filter =
 
270
      new SingleColumnValueFilter(Bytes.toBytes("trans-tags"),
 
271
        Bytes.toBytes("qual2"), CompareOp.EQUAL, Bytes.toBytes(value));
 
272
    filter.setFilterIfMissing(true);
 
273
    allFilters.addFilter(filter);
 
274
    Scan scan = new Scan();
 
275
    scan.addFamily(Bytes.toBytes("trans-blob"));
 
276
    scan.addFamily(Bytes.toBytes("trans-type"));
 
277
    scan.addFamily(Bytes.toBytes("trans-date"));
 
278
    scan.addFamily(Bytes.toBytes("trans-tags"));
 
279
    scan.addFamily(Bytes.toBytes("trans-group"));
 
280
    scan.setFilter(allFilters);
 
281
    return r.getScanner(scan);
 
282
  }
 
283
 
 
284
  private void putRows(HRegion r, int numRows, String value, String key)
 
285
  throws IOException {
 
286
    for (int i = 0; i < numRows; i++) {
 
287
      String row = key + "_" + i/* UUID.randomUUID().toString() */;
 
288
      System.out.println(String.format("Saving row: %s, with value %s", row,
 
289
        value));
 
290
      Put put = new Put(Bytes.toBytes(row));
 
291
      put.add(Bytes.toBytes("trans-blob"), null,
 
292
        Bytes.toBytes("value for blob"));
 
293
      put.add(Bytes.toBytes("trans-type"), null, Bytes.toBytes("statement"));
 
294
      put.add(Bytes.toBytes("trans-date"), null,
 
295
        Bytes.toBytes("20090921010101999"));
 
296
      put.add(Bytes.toBytes("trans-tags"), Bytes.toBytes("qual2"),
 
297
        Bytes.toBytes(value));
 
298
      put.add(Bytes.toBytes("trans-group"), null,
 
299
        Bytes.toBytes("adhocTransactionGroupId"));
 
300
      r.put(put);
 
301
    }
 
302
  }
 
303
 
 
304
  public void testFamilyWithAndWithoutColon() throws Exception {
 
305
    byte [] b = Bytes.toBytes(getName());
 
306
    byte [] cf = Bytes.toBytes("cf");
 
307
    initHRegion(b, getName(), cf);
 
308
    Put p = new Put(b);
 
309
    byte [] cfwithcolon = Bytes.toBytes("cf:");
 
310
    p.add(cfwithcolon, cfwithcolon, cfwithcolon);
 
311
    boolean exception = false;
 
312
    try {
 
313
      this.region.put(p);
 
314
    } catch (NoSuchColumnFamilyException e) {
 
315
      exception = true;
 
316
    }
 
317
    assertTrue(exception);
 
318
    // Can I add it using old style call?
 
319
    p = new Put(b);
 
320
    p.add(cfwithcolon, System.currentTimeMillis(), cfwithcolon);
 
321
    this.region.put(p);
 
322
  }
 
323
 
 
324
  //////////////////////////////////////////////////////////////////////////////
 
325
  // checkAndPut tests
 
326
  //////////////////////////////////////////////////////////////////////////////
 
327
  public void testCheckAndPut_WithEmptyRowValue() throws IOException {
 
328
    byte [] tableName = Bytes.toBytes("testtable");
 
329
    byte [] row1 = Bytes.toBytes("row1");
 
330
    byte [] fam1 = Bytes.toBytes("fam1");
 
331
    byte [] qf1  = Bytes.toBytes("qualifier");
 
332
    byte [] emptyVal  = new byte[] {};
 
333
    byte [] val1  = Bytes.toBytes("value1");
 
334
    byte [] val2  = Bytes.toBytes("value2");
 
335
    Integer lockId = null;
 
336
    
 
337
    //Setting up region
 
338
    String method = this.getName();
 
339
    initHRegion(tableName, method, fam1);
 
340
    //Putting data in key
 
341
    Put put = new Put(row1);
 
342
    put.add(fam1, qf1, val1);
 
343
 
 
344
    //checkAndPut with correct value
 
345
    boolean res = region.checkAndPut(row1, fam1, qf1, emptyVal, put, lockId,
 
346
        true);
 
347
    assertTrue(res);
 
348
 
 
349
    // not empty anymore
 
350
    res = region.checkAndPut(row1, fam1, qf1, emptyVal, put, lockId, true);
 
351
    assertFalse(res);
 
352
 
 
353
    put = new Put(row1);
 
354
    put.add(fam1, qf1, val2);
 
355
    //checkAndPut with correct value
 
356
    res = region.checkAndPut(row1, fam1, qf1, val1, put, lockId, true);
 
357
    assertTrue(res);
 
358
  }
 
359
  
 
360
  public void testCheckAndPut_WithWrongValue() throws IOException{
 
361
    byte [] tableName = Bytes.toBytes("testtable");
 
362
    byte [] row1 = Bytes.toBytes("row1");
 
363
    byte [] fam1 = Bytes.toBytes("fam1");
 
364
    byte [] qf1  = Bytes.toBytes("qualifier");
 
365
    byte [] val1  = Bytes.toBytes("value1");
 
366
    byte [] val2  = Bytes.toBytes("value2");
 
367
    Integer lockId = null;
 
368
 
 
369
    //Setting up region
 
370
    String method = this.getName();
 
371
    initHRegion(tableName, method, fam1);
 
372
 
 
373
    //Putting data in key
 
374
    Put put = new Put(row1);
 
375
    put.add(fam1, qf1, val1);
 
376
    region.put(put);
 
377
    
 
378
    //checkAndPut with wrong value
 
379
    boolean res = region.checkAndPut(row1, fam1, qf1, val2, put, lockId, true);
 
380
    assertEquals(false, res);
 
381
  }
 
382
 
 
383
  public void testCheckAndPut_WithCorrectValue() throws IOException{
 
384
    byte [] tableName = Bytes.toBytes("testtable");
 
385
    byte [] row1 = Bytes.toBytes("row1");
 
386
    byte [] fam1 = Bytes.toBytes("fam1");
 
387
    byte [] qf1  = Bytes.toBytes("qualifier");
 
388
    byte [] val1  = Bytes.toBytes("value1");
 
389
    Integer lockId = null;
 
390
 
 
391
    //Setting up region
 
392
    String method = this.getName();
 
393
    initHRegion(tableName, method, fam1);
 
394
 
 
395
    //Putting data in key
 
396
    Put put = new Put(row1);
 
397
    put.add(fam1, qf1, val1);
 
398
    region.put(put);
 
399
    
 
400
    //checkAndPut with correct value
 
401
    boolean res = region.checkAndPut(row1, fam1, qf1, val1, put, lockId, true);
 
402
    assertEquals(true, res);
 
403
  }
 
404
  
 
405
  public void testCheckAndPut_ThatPutWasWritten() throws IOException{
 
406
    byte [] tableName = Bytes.toBytes("testtable");
 
407
    byte [] row1 = Bytes.toBytes("row1");
 
408
    byte [] fam1 = Bytes.toBytes("fam1");
 
409
    byte [] fam2 = Bytes.toBytes("fam2");
 
410
    byte [] qf1  = Bytes.toBytes("qualifier");
 
411
    byte [] val1  = Bytes.toBytes("value1");
 
412
    byte [] val2  = Bytes.toBytes("value2");
 
413
    Integer lockId = null;
 
414
 
 
415
    byte [][] families = {fam1, fam2};
 
416
    
 
417
    //Setting up region
 
418
    String method = this.getName();
 
419
    initHRegion(tableName, method, families);
 
420
 
 
421
    //Putting data in the key to check
 
422
    Put put = new Put(row1);
 
423
    put.add(fam1, qf1, val1);
 
424
    region.put(put);
 
425
    
 
426
    //Creating put to add
 
427
    long ts = System.currentTimeMillis();
 
428
    KeyValue kv = new KeyValue(row1, fam2, qf1, ts, KeyValue.Type.Put, val2);
 
429
    put = new Put(row1);
 
430
    put.add(kv);
 
431
    
 
432
    //checkAndPut with wrong value
 
433
    Store store = region.getStore(fam1);
 
434
    store.memstore.kvset.size();
 
435
    
 
436
    boolean res = region.checkAndPut(row1, fam1, qf1, val1, put, lockId, true);
 
437
    assertEquals(true, res);
 
438
    store.memstore.kvset.size();
 
439
    
 
440
    Get get = new Get(row1);
 
441
    get.addColumn(fam2, qf1);
 
442
    KeyValue [] actual = region.get(get, null).raw();
 
443
    
 
444
    KeyValue [] expected = {kv};
 
445
    
 
446
    assertEquals(expected.length, actual.length);
 
447
    for(int i=0; i<actual.length; i++) {
 
448
      assertEquals(expected[i], actual[i]);
 
449
    }
 
450
    
 
451
  }
 
452
  
 
453
  //////////////////////////////////////////////////////////////////////////////
 
454
  // Delete tests
 
455
  //////////////////////////////////////////////////////////////////////////////
 
456
  public void testDelete_multiDeleteColumn() throws IOException {
 
457
    byte [] tableName = Bytes.toBytes("testtable");
 
458
    byte [] row1 = Bytes.toBytes("row1");
 
459
    byte [] fam1 = Bytes.toBytes("fam1");
 
460
    byte [] qual = Bytes.toBytes("qualifier");
 
461
    byte [] value = Bytes.toBytes("value");
 
462
 
 
463
    Put put = new Put(row1);
 
464
    put.add(fam1, qual, 1, value);
 
465
    put.add(fam1, qual, 2, value);
 
466
 
 
467
    String method = this.getName();
 
468
    initHRegion(tableName, method, fam1);
 
469
 
 
470
    region.put(put);
 
471
 
 
472
    Delete delete = new Delete(row1);
 
473
    delete.deleteColumn(fam1, qual);
 
474
    delete.deleteColumn(fam1, qual);
 
475
    region.delete(delete, null, false);
 
476
 
 
477
    Get get = new Get(row1);
 
478
    get.addFamily(fam1);
 
479
    Result r = region.get(get, null);
 
480
    assertEquals(0, r.size());
 
481
  }
 
482
 
 
483
  public void testDelete_CheckFamily() throws IOException {
 
484
    byte [] tableName = Bytes.toBytes("testtable");
 
485
    byte [] row1 = Bytes.toBytes("row1");
 
486
    byte [] fam1 = Bytes.toBytes("fam1");
 
487
    byte [] fam2 = Bytes.toBytes("fam2");
 
488
    byte [] fam3 = Bytes.toBytes("fam3");
 
489
    byte [] fam4 = Bytes.toBytes("fam4");
 
490
 
 
491
    //Setting up region
 
492
    String method = this.getName();
 
493
    initHRegion(tableName, method, fam1, fam2, fam3);
 
494
 
 
495
    List<KeyValue> kvs  = new ArrayList<KeyValue>();
 
496
    kvs.add(new KeyValue(row1, fam4, null, null));
 
497
 
 
498
 
 
499
    //testing existing family
 
500
    byte [] family = fam2;
 
501
    try {
 
502
      region.delete(family, kvs, true);
 
503
    } catch (Exception e) {
 
504
      assertTrue("Family " +new String(family)+ " does not exist", false);
 
505
    }
 
506
 
 
507
    //testing non existing family 
 
508
    boolean ok = false; 
 
509
    family = fam4;
 
510
    try {
 
511
      region.delete(family, kvs, true);
 
512
    } catch (Exception e) {
 
513
      ok = true;
 
514
    }
 
515
    assertEquals("Family " +new String(family)+ " does exist", true, ok);
 
516
  }
 
517
 
 
518
  public void testDelete_mixed() throws IOException {
 
519
    byte [] tableName = Bytes.toBytes("testtable");
 
520
    byte [] fam = Bytes.toBytes("info");
 
521
    byte [][] families = {fam};
 
522
    String method = this.getName();
 
523
    initHRegion(tableName, method, families);
 
524
 
 
525
    byte [] row = Bytes.toBytes("table_name");
 
526
    // column names
 
527
    byte [] serverinfo = Bytes.toBytes("serverinfo");
 
528
    byte [] splitA = Bytes.toBytes("splitA");
 
529
    byte [] splitB = Bytes.toBytes("splitB");
 
530
 
 
531
    // add some data:
 
532
    Put put = new Put(row);
 
533
    put.add(fam, splitA, Bytes.toBytes("reference_A"));
 
534
    region.put(put);
 
535
 
 
536
    put = new Put(row);
 
537
    put.add(fam, splitB, Bytes.toBytes("reference_B"));
 
538
    region.put(put);
 
539
 
 
540
    put = new Put(row);
 
541
    put.add(fam, serverinfo, Bytes.toBytes("ip_address"));
 
542
    region.put(put);
 
543
 
 
544
    // ok now delete a split:
 
545
    Delete delete = new Delete(row);
 
546
    delete.deleteColumns(fam, splitA);
 
547
    region.delete(delete, null, true);
 
548
 
 
549
    // assert some things:
 
550
    Get get = new Get(row).addColumn(fam, serverinfo);
 
551
    Result result = region.get(get, null);
 
552
    assertEquals(1, result.size());
 
553
 
 
554
    get = new Get(row).addColumn(fam, splitA);
 
555
    result = region.get(get, null);
 
556
    assertEquals(0, result.size());
 
557
 
 
558
    get = new Get(row).addColumn(fam, splitB);
 
559
    result = region.get(get, null);
 
560
    assertEquals(1, result.size());
 
561
  }
 
562
  
 
563
  public void testDeleteRowWithFutureTs() throws IOException {
 
564
    byte [] tableName = Bytes.toBytes("testtable");
 
565
    byte [] fam = Bytes.toBytes("info");
 
566
    byte [][] families = {fam};
 
567
    String method = this.getName();
 
568
    initHRegion(tableName, method, families);
 
569
 
 
570
    byte [] row = Bytes.toBytes("table_name");
 
571
    // column names
 
572
    byte [] serverinfo = Bytes.toBytes("serverinfo");
 
573
 
 
574
    // add data in the far future
 
575
    Put put = new Put(row);
 
576
    put.add(fam, serverinfo, HConstants.LATEST_TIMESTAMP-5,Bytes.toBytes("value"));
 
577
    region.put(put);
 
578
 
 
579
    // now delete something in the present
 
580
    Delete delete = new Delete(row);
 
581
    region.delete(delete, null, true);
 
582
 
 
583
    // make sure we still see our data
 
584
    Get get = new Get(row).addColumn(fam, serverinfo);
 
585
    Result result = region.get(get, null);
 
586
    assertEquals(1, result.size());
 
587
    
 
588
    // delete the future row
 
589
    delete = new Delete(row,HConstants.LATEST_TIMESTAMP-3,null);
 
590
    region.delete(delete, null, true);
 
591
 
 
592
    // make sure it is gone
 
593
    get = new Get(row).addColumn(fam, serverinfo);
 
594
    result = region.get(get, null);
 
595
    assertEquals(0, result.size());
 
596
  }
 
597
 
 
598
  public void testScanner_DeleteOneFamilyNotAnother() throws IOException {
 
599
    byte [] tableName = Bytes.toBytes("test_table");
 
600
    byte [] fam1 = Bytes.toBytes("columnA");
 
601
    byte [] fam2 = Bytes.toBytes("columnB");
 
602
    initHRegion(tableName, getName(), fam1, fam2);
 
603
 
 
604
    byte [] rowA = Bytes.toBytes("rowA");
 
605
    byte [] rowB = Bytes.toBytes("rowB");
 
606
 
 
607
    byte [] value = Bytes.toBytes("value");
 
608
 
 
609
    Delete delete = new Delete(rowA);
 
610
    delete.deleteFamily(fam1);
 
611
 
 
612
    region.delete(delete, null, true);
 
613
 
 
614
    // now create data.
 
615
    Put put = new Put(rowA);
 
616
    put.add(fam2, null, value);
 
617
    region.put(put);
 
618
 
 
619
    put = new Put(rowB);
 
620
    put.add(fam1, null, value);
 
621
    put.add(fam2, null, value);
 
622
    region.put(put);
 
623
 
 
624
    Scan scan = new Scan();
 
625
    scan.addFamily(fam1).addFamily(fam2);
 
626
    InternalScanner s = region.getScanner(scan);
 
627
    List<KeyValue> results = new ArrayList<KeyValue>();
 
628
    s.next(results);
 
629
    assertTrue(Bytes.equals(rowA, results.get(0).getRow()));
 
630
 
 
631
    results.clear();
 
632
    s.next(results);
 
633
    assertTrue(Bytes.equals(rowB, results.get(0).getRow()));
 
634
 
 
635
  }
 
636
 
 
637
  public void testDeleteColumns_PostInsert() throws IOException,
 
638
      InterruptedException {
 
639
    Delete delete = new Delete(row);
 
640
    delete.deleteColumns(fam1, qual1);
 
641
    doTestDelete_AndPostInsert(delete);
 
642
  }
 
643
 
 
644
  public void testDeleteFamily_PostInsert() throws IOException, InterruptedException {
 
645
    Delete delete = new Delete(row);
 
646
    delete.deleteFamily(fam1);
 
647
    doTestDelete_AndPostInsert(delete);
 
648
  }
 
649
 
 
650
  public void doTestDelete_AndPostInsert(Delete delete)
 
651
      throws IOException, InterruptedException {
 
652
    initHRegion(tableName, getName(), fam1);
 
653
    Put put = new Put(row);
 
654
    put.add(fam1, qual1, value1);
 
655
    region.put(put);
 
656
 
 
657
    Thread.sleep(10);
 
658
    
 
659
    // now delete the value:
 
660
    region.delete(delete, null, true);
 
661
 
 
662
    Thread.sleep(10);
 
663
 
 
664
    // ok put data:
 
665
    put = new Put(row);
 
666
    put.add(fam1, qual1, value2);
 
667
    region.put(put);
 
668
 
 
669
    // ok get:
 
670
    Get get = new Get(row);
 
671
    get.addColumn(fam1, qual1);
 
672
 
 
673
    Result r = region.get(get, null);
 
674
    assertEquals(1, r.size());
 
675
    assertByteEquals(value2, r.getValue(fam1, qual1));
 
676
 
 
677
    // next:
 
678
    Scan scan = new Scan(row);
 
679
    scan.addColumn(fam1, qual1);
 
680
    InternalScanner s = region.getScanner(scan);
 
681
 
 
682
    List<KeyValue> results = new ArrayList<KeyValue>();
 
683
    assertEquals(false, s.next(results));
 
684
    assertEquals(1, results.size());
 
685
    KeyValue kv = results.get(0);
 
686
 
 
687
    assertByteEquals(value2, kv.getValue());
 
688
    assertByteEquals(fam1, kv.getFamily());
 
689
    assertByteEquals(qual1, kv.getQualifier());
 
690
    assertByteEquals(row, kv.getRow());
 
691
  }
 
692
 
 
693
 
 
694
  
 
695
  public void testDelete_CheckTimestampUpdated()
 
696
  throws IOException {
 
697
    byte [] row1 = Bytes.toBytes("row1");
 
698
    byte [] col1 = Bytes.toBytes("col1");
 
699
    byte [] col2 = Bytes.toBytes("col2");
 
700
    byte [] col3 = Bytes.toBytes("col3");
 
701
    
 
702
    //Setting up region
 
703
    String method = this.getName();
 
704
    initHRegion(tableName, method, fam1);
 
705
    
 
706
    //Building checkerList 
 
707
    List<KeyValue> kvs  = new ArrayList<KeyValue>();
 
708
    kvs.add(new KeyValue(row1, fam1, col1, null));
 
709
    kvs.add(new KeyValue(row1, fam1, col2, null));
 
710
    kvs.add(new KeyValue(row1, fam1, col3, null));
 
711
 
 
712
    region.delete(fam1, kvs, true);
 
713
 
 
714
    // extract the key values out the memstore:
 
715
    // This is kinda hacky, but better than nothing...
 
716
    long now = System.currentTimeMillis();
 
717
    KeyValue firstKv = region.getStore(fam1).memstore.kvset.first();
 
718
    assertTrue(firstKv.getTimestamp() <= now);
 
719
    now = firstKv.getTimestamp();
 
720
    for (KeyValue kv: region.getStore(fam1).memstore.kvset) {
 
721
      assertTrue(kv.getTimestamp() <= now);
 
722
      now = kv.getTimestamp();
 
723
    }
 
724
  }
 
725
  
 
726
  //////////////////////////////////////////////////////////////////////////////
 
727
  // Get tests
 
728
  //////////////////////////////////////////////////////////////////////////////
 
729
  public void testGet_FamilyChecker() throws IOException {
 
730
    byte [] tableName = Bytes.toBytes("testtable");
 
731
    byte [] row1 = Bytes.toBytes("row1");
 
732
    byte [] fam1 = Bytes.toBytes("fam1");
 
733
    byte [] fam2 = Bytes.toBytes("False");
 
734
    byte [] col1 = Bytes.toBytes("col1");
 
735
    
 
736
    //Setting up region
 
737
    String method = this.getName();
 
738
    initHRegion(tableName, method, fam1);
 
739
    
 
740
    Get get = new Get(row1);
 
741
    get.addColumn(fam2, col1);
 
742
    
 
743
    //Test
 
744
    try {
 
745
      region.get(get, null);
 
746
    } catch (NoSuchColumnFamilyException e){
 
747
      assertFalse(false);
 
748
      return;
 
749
    }
 
750
    assertFalse(true);
 
751
  }
 
752
 
 
753
  public void testGet_Basic() throws IOException {
 
754
    byte [] tableName = Bytes.toBytes("testtable");
 
755
    byte [] row1 = Bytes.toBytes("row1");
 
756
    byte [] fam1 = Bytes.toBytes("fam1");
 
757
    byte [] col1 = Bytes.toBytes("col1");
 
758
    byte [] col2 = Bytes.toBytes("col2");
 
759
    byte [] col3 = Bytes.toBytes("col3");
 
760
    byte [] col4 = Bytes.toBytes("col4");
 
761
    byte [] col5 = Bytes.toBytes("col5");
 
762
    
 
763
    //Setting up region
 
764
    String method = this.getName();
 
765
    initHRegion(tableName, method, fam1);
 
766
    
 
767
    //Add to memstore
 
768
    Put put = new Put(row1);
 
769
    put.add(fam1, col1, null);
 
770
    put.add(fam1, col2, null);
 
771
    put.add(fam1, col3, null);
 
772
    put.add(fam1, col4, null);
 
773
    put.add(fam1, col5, null);
 
774
    region.put(put);
 
775
 
 
776
    Get get = new Get(row1);
 
777
    get.addColumn(fam1, col2);
 
778
    get.addColumn(fam1, col4);
 
779
    //Expected result
 
780
    KeyValue kv1 = new KeyValue(row1, fam1, col2);
 
781
    KeyValue kv2 = new KeyValue(row1, fam1, col4);
 
782
    KeyValue [] expected = {kv1, kv2};
 
783
 
 
784
    //Test
 
785
    Result res = region.get(get, null);
 
786
    assertEquals(expected.length, res.size());
 
787
    for(int i=0; i<res.size(); i++){
 
788
      assertEquals(0,
 
789
          Bytes.compareTo(expected[i].getRow(), res.raw()[i].getRow()));
 
790
      assertEquals(0,
 
791
          Bytes.compareTo(expected[i].getFamily(), res.raw()[i].getFamily()));
 
792
      assertEquals(0,
 
793
          Bytes.compareTo(
 
794
              expected[i].getQualifier(), res.raw()[i].getQualifier()));
 
795
    }
 
796
 
 
797
    // Test using a filter on a Get
 
798
    Get g = new Get(row1);
 
799
    final int count = 2;
 
800
    g.setFilter(new ColumnCountGetFilter(count));
 
801
    res = region.get(g, null);
 
802
    assertEquals(count, res.size());
 
803
  }
 
804
 
 
805
  public void testGet_Empty() throws IOException {
 
806
    byte [] tableName = Bytes.toBytes("emptytable");
 
807
    byte [] row = Bytes.toBytes("row");
 
808
    byte [] fam = Bytes.toBytes("fam");
 
809
    
 
810
    String method = this.getName();
 
811
    initHRegion(tableName, method, fam);
 
812
    
 
813
    Get get = new Get(row);
 
814
    get.addFamily(fam);
 
815
    Result r = region.get(get, null);
 
816
    
 
817
    assertTrue(r.isEmpty());
 
818
  }
 
819
  
 
820
  //Test that checked if there was anything special when reading from the ROOT
 
821
  //table. To be able to use this test you need to comment the part in
 
822
  //HTableDescriptor that checks for '-' and '.'. You also need to remove the
 
823
  //s in the beginning of the name.
 
824
  public void stestGet_Root() throws IOException {
 
825
    //Setting up region
 
826
    String method = this.getName();
 
827
    initHRegion(HConstants.ROOT_TABLE_NAME, method, HConstants.CATALOG_FAMILY);
 
828
 
 
829
    //Add to memstore
 
830
    Put put = new Put(HConstants.EMPTY_START_ROW);
 
831
    put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, null);
 
832
    region.put(put);
 
833
    
 
834
    Get get = new Get(HConstants.EMPTY_START_ROW);
 
835
    get.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
 
836
 
 
837
    //Expected result
 
838
    KeyValue kv1 = new KeyValue(HConstants.EMPTY_START_ROW,
 
839
        HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
 
840
    KeyValue [] expected = {kv1};
 
841
    
 
842
    //Test from memstore
 
843
    Result res = region.get(get, null);
 
844
    
 
845
    assertEquals(expected.length, res.size());
 
846
    for(int i=0; i<res.size(); i++){
 
847
      assertEquals(0,
 
848
          Bytes.compareTo(expected[i].getRow(), res.raw()[i].getRow()));
 
849
      assertEquals(0,
 
850
          Bytes.compareTo(expected[i].getFamily(), res.raw()[i].getFamily()));
 
851
      assertEquals(0,
 
852
          Bytes.compareTo(
 
853
              expected[i].getQualifier(), res.raw()[i].getQualifier()));
 
854
    }
 
855
    
 
856
    //flush
 
857
    region.flushcache();
 
858
    
 
859
    //test2
 
860
    res = region.get(get, null);
 
861
    
 
862
    assertEquals(expected.length, res.size());
 
863
    for(int i=0; i<res.size(); i++){
 
864
      assertEquals(0,
 
865
          Bytes.compareTo(expected[i].getRow(), res.raw()[i].getRow()));
 
866
      assertEquals(0,
 
867
          Bytes.compareTo(expected[i].getFamily(), res.raw()[i].getFamily()));
 
868
      assertEquals(0,
 
869
          Bytes.compareTo(
 
870
              expected[i].getQualifier(), res.raw()[i].getQualifier()));
 
871
    }
 
872
    
 
873
    //Scan
 
874
    Scan scan = new Scan();
 
875
    scan.addFamily(HConstants.CATALOG_FAMILY);
 
876
    InternalScanner s = region.getScanner(scan);
 
877
    List<KeyValue> result = new ArrayList<KeyValue>();
 
878
    s.next(result);
 
879
    
 
880
    assertEquals(expected.length, result.size());
 
881
    for(int i=0; i<res.size(); i++){
 
882
      assertEquals(0,
 
883
          Bytes.compareTo(expected[i].getRow(), result.get(i).getRow()));
 
884
      assertEquals(0,
 
885
          Bytes.compareTo(expected[i].getFamily(), result.get(i).getFamily()));
 
886
      assertEquals(0,
 
887
          Bytes.compareTo(
 
888
              expected[i].getQualifier(), result.get(i).getQualifier()));
 
889
    }
 
890
  }  
 
891
  
 
892
  //////////////////////////////////////////////////////////////////////////////
 
893
  // Lock test
 
894
  ////////////////////////////////////////////////////////////////////////////// 
 
895
  public void testLocks() throws IOException{
 
896
    byte [] tableName = Bytes.toBytes("testtable");
 
897
    byte [][] families = {fam1, fam2, fam3};
 
898
    
 
899
    HBaseConfiguration hc = initSplit();
 
900
    //Setting up region
 
901
    String method = this.getName();
 
902
    initHRegion(tableName, method, hc, families);
 
903
    
 
904
    final int threadCount = 10;
 
905
    final int lockCount = 10;
 
906
    
 
907
    List<Thread>threads = new ArrayList<Thread>(threadCount);
 
908
    for (int i = 0; i < threadCount; i++) {
 
909
      threads.add(new Thread(Integer.toString(i)) {
 
910
        @Override
 
911
        public void run() {
 
912
          Integer [] lockids = new Integer[lockCount];
 
913
          // Get locks.
 
914
          for (int i = 0; i < lockCount; i++) {
 
915
            try {
 
916
              byte [] rowid = Bytes.toBytes(Integer.toString(i));
 
917
              lockids[i] = region.obtainRowLock(rowid);
 
918
              assertEquals(rowid, region.getRowFromLock(lockids[i]));
 
919
              LOG.debug(getName() + " locked " + Bytes.toString(rowid));
 
920
            } catch (IOException e) {
 
921
              e.printStackTrace();
 
922
            }
 
923
          }
 
924
          LOG.debug(getName() + " set " +
 
925
              Integer.toString(lockCount) + " locks");
 
926
          
 
927
          // Abort outstanding locks.
 
928
          for (int i = lockCount - 1; i >= 0; i--) {
 
929
            region.releaseRowLock(lockids[i]);
 
930
            LOG.debug(getName() + " unlocked " + i);
 
931
          }
 
932
          LOG.debug(getName() + " released " +
 
933
              Integer.toString(lockCount) + " locks");
 
934
        }
 
935
      });
 
936
    }
 
937
    
 
938
    // Startup all our threads.
 
939
    for (Thread t : threads) {
 
940
      t.start();
 
941
    }
 
942
    
 
943
    // Now wait around till all are done.
 
944
    for (Thread t: threads) {
 
945
      while (t.isAlive()) {
 
946
        try {
 
947
          Thread.sleep(1);
 
948
        } catch (InterruptedException e) {
 
949
          // Go around again.
 
950
        }
 
951
      }
 
952
    }
 
953
    LOG.info("locks completed.");
 
954
  }
 
955
  
 
956
  //////////////////////////////////////////////////////////////////////////////
 
957
  // Merge test
 
958
  ////////////////////////////////////////////////////////////////////////////// 
 
959
  public void testMerge() throws IOException {
 
960
    byte [] tableName = Bytes.toBytes("testtable");
 
961
    byte [][] families = {fam1, fam2, fam3};
 
962
    
 
963
    HBaseConfiguration hc = initSplit();
 
964
    //Setting up region
 
965
    String method = this.getName();
 
966
    initHRegion(tableName, method, hc, families);
 
967
    
 
968
    try {
 
969
      LOG.info("" + addContent(region, fam3));
 
970
      region.flushcache();
 
971
      byte [] splitRow = region.compactStores();
 
972
      assertNotNull(splitRow);
 
973
      LOG.info("SplitRow: " + Bytes.toString(splitRow));
 
974
      HRegion [] regions = split(region, splitRow);
 
975
      try {
 
976
        // Need to open the regions.
 
977
        // TODO: Add an 'open' to HRegion... don't do open by constructing
 
978
        // instance.
 
979
        for (int i = 0; i < regions.length; i++) {
 
980
          regions[i] = openClosedRegion(regions[i]);
 
981
        }
 
982
        Path oldRegionPath = region.getRegionDir();
 
983
        long startTime = System.currentTimeMillis();
 
984
        HRegion subregions [] = region.splitRegion(splitRow);
 
985
        if (subregions != null) {
 
986
          LOG.info("Split region elapsed time: "
 
987
              + ((System.currentTimeMillis() - startTime) / 1000.0));
 
988
          assertEquals("Number of subregions", subregions.length, 2);
 
989
          for (int i = 0; i < subregions.length; i++) {
 
990
            subregions[i] = openClosedRegion(subregions[i]);
 
991
            subregions[i].compactStores();
 
992
          }
 
993
 
 
994
          // Now merge it back together
 
995
          Path oldRegion1 = subregions[0].getRegionDir();
 
996
          Path oldRegion2 = subregions[1].getRegionDir();
 
997
          startTime = System.currentTimeMillis();
 
998
          region = HRegion.mergeAdjacent(subregions[0], subregions[1]);
 
999
          LOG.info("Merge regions elapsed time: " +
 
1000
              ((System.currentTimeMillis() - startTime) / 1000.0));
 
1001
          fs.delete(oldRegion1, true);
 
1002
          fs.delete(oldRegion2, true);
 
1003
          fs.delete(oldRegionPath, true);
 
1004
        }
 
1005
        LOG.info("splitAndMerge completed.");
 
1006
      } finally {
 
1007
        for (int i = 0; i < regions.length; i++) {
 
1008
          try {
 
1009
            regions[i].close();
 
1010
          } catch (IOException e) {
 
1011
            // Ignore.
 
1012
          }
 
1013
        }
 
1014
      }
 
1015
    } finally {
 
1016
      if (region != null) {
 
1017
        region.close();
 
1018
        region.getLog().closeAndDelete();
 
1019
      }
 
1020
    }
 
1021
  }
 
1022
  
 
1023
  //////////////////////////////////////////////////////////////////////////////
 
1024
  // Scanner tests
 
1025
  //////////////////////////////////////////////////////////////////////////////
 
1026
  public void testGetScanner_WithOkFamilies() throws IOException {
 
1027
    byte [] tableName = Bytes.toBytes("testtable");
 
1028
    byte [] fam1 = Bytes.toBytes("fam1");
 
1029
    byte [] fam2 = Bytes.toBytes("fam2");
 
1030
    
 
1031
    byte [][] families = {fam1, fam2};
 
1032
    
 
1033
    //Setting up region
 
1034
    String method = this.getName();
 
1035
    initHRegion(tableName, method, families);
 
1036
    
 
1037
    Scan scan = new Scan();
 
1038
    scan.addFamily(fam1);
 
1039
    scan.addFamily(fam2);
 
1040
    try {
 
1041
      region.getScanner(scan);
 
1042
    } catch (Exception e) {
 
1043
      assertTrue("Families could not be found in Region", false);
 
1044
    }
 
1045
  }
 
1046
  
 
1047
  public void testGetScanner_WithNotOkFamilies() throws IOException {
 
1048
    byte [] tableName = Bytes.toBytes("testtable");
 
1049
    byte [] fam1 = Bytes.toBytes("fam1");
 
1050
    byte [] fam2 = Bytes.toBytes("fam2");
 
1051
 
 
1052
    byte [][] families = {fam1};
 
1053
 
 
1054
    //Setting up region
 
1055
    String method = this.getName();
 
1056
    initHRegion(tableName, method, families);
 
1057
 
 
1058
    Scan scan = new Scan();
 
1059
    scan.addFamily(fam2);
 
1060
    boolean ok = false;
 
1061
    try {
 
1062
      region.getScanner(scan);
 
1063
    } catch (Exception e) {
 
1064
      ok = true;
 
1065
    }
 
1066
    assertTrue("Families could not be found in Region", ok);
 
1067
  }
 
1068
  
 
1069
  public void testGetScanner_WithNoFamilies() throws IOException {
 
1070
    byte [] tableName = Bytes.toBytes("testtable");
 
1071
    byte [] row1 = Bytes.toBytes("row1");
 
1072
    byte [] fam1 = Bytes.toBytes("fam1");
 
1073
    byte [] fam2 = Bytes.toBytes("fam2");
 
1074
    byte [] fam3 = Bytes.toBytes("fam3");
 
1075
    byte [] fam4 = Bytes.toBytes("fam4");
 
1076
    
 
1077
    byte [][] families = {fam1, fam2, fam3, fam4};
 
1078
    
 
1079
    //Setting up region
 
1080
    String method = this.getName();
 
1081
    initHRegion(tableName, method, families);
 
1082
    
 
1083
 
 
1084
    //Putting data in Region
 
1085
    Put put = new Put(row1);
 
1086
    put.add(fam1, null, null);
 
1087
    put.add(fam2, null, null);
 
1088
    put.add(fam3, null, null);
 
1089
    put.add(fam4, null, null);
 
1090
    region.put(put);
 
1091
    
 
1092
    Scan scan = null;
 
1093
    HRegion.RegionScanner is = null;
 
1094
    
 
1095
    //Testing to see how many scanners that is produced by getScanner, starting 
 
1096
    //with known number, 2 - current = 1
 
1097
    scan = new Scan();
 
1098
    scan.addFamily(fam2);
 
1099
    scan.addFamily(fam4);
 
1100
    is = (RegionScanner) region.getScanner(scan);
 
1101
    is.initHeap(); // i dont like this test
 
1102
    assertEquals(1, ((RegionScanner)is).storeHeap.getHeap().size());
 
1103
    
 
1104
    scan = new Scan();
 
1105
    is = (RegionScanner) region.getScanner(scan);
 
1106
    is.initHeap();
 
1107
    assertEquals(families.length -1, 
 
1108
        ((RegionScanner)is).storeHeap.getHeap().size());
 
1109
  }
 
1110
 
 
1111
  public void testRegionScanner_Next() throws IOException {
 
1112
    byte [] tableName = Bytes.toBytes("testtable");
 
1113
    byte [] row1 = Bytes.toBytes("row1");
 
1114
    byte [] row2 = Bytes.toBytes("row2");
 
1115
    byte [] fam1 = Bytes.toBytes("fam1");
 
1116
    byte [] fam2 = Bytes.toBytes("fam2");
 
1117
    byte [] fam3 = Bytes.toBytes("fam3");
 
1118
    byte [] fam4 = Bytes.toBytes("fam4");
 
1119
    
 
1120
    byte [][] families = {fam1, fam2, fam3, fam4};
 
1121
    long ts = System.currentTimeMillis();
 
1122
    
 
1123
    //Setting up region
 
1124
    String method = this.getName();
 
1125
    initHRegion(tableName, method, families);
 
1126
    
 
1127
    //Putting data in Region
 
1128
    Put put = null;
 
1129
    put = new Put(row1);
 
1130
    put.add(fam1, null, ts, null);
 
1131
    put.add(fam2, null, ts, null);
 
1132
    put.add(fam3, null, ts, null);
 
1133
    put.add(fam4, null, ts, null);
 
1134
    region.put(put);
 
1135
 
 
1136
    put = new Put(row2);
 
1137
    put.add(fam1, null, ts, null);
 
1138
    put.add(fam2, null, ts, null);
 
1139
    put.add(fam3, null, ts, null);
 
1140
    put.add(fam4, null, ts, null);
 
1141
    region.put(put);
 
1142
    
 
1143
    Scan scan = new Scan();
 
1144
    scan.addFamily(fam2);
 
1145
    scan.addFamily(fam4);
 
1146
    InternalScanner is = region.getScanner(scan);
 
1147
    
 
1148
    List<KeyValue> res = null;
 
1149
    
 
1150
    //Result 1
 
1151
    List<KeyValue> expected1 = new ArrayList<KeyValue>();
 
1152
    expected1.add(new KeyValue(row1, fam2, null, ts, KeyValue.Type.Put, null));
 
1153
    expected1.add(new KeyValue(row1, fam4, null, ts, KeyValue.Type.Put, null));
 
1154
    
 
1155
    res = new ArrayList<KeyValue>();
 
1156
    is.next(res);
 
1157
    for(int i=0; i<res.size(); i++) {
 
1158
      assertEquals(expected1.get(i), res.get(i));
 
1159
    }
 
1160
    
 
1161
    //Result 2
 
1162
    List<KeyValue> expected2 = new ArrayList<KeyValue>();
 
1163
    expected2.add(new KeyValue(row2, fam2, null, ts, KeyValue.Type.Put, null));
 
1164
    expected2.add(new KeyValue(row2, fam4, null, ts, KeyValue.Type.Put, null));
 
1165
    
 
1166
    res = new ArrayList<KeyValue>();
 
1167
    is.next(res);
 
1168
    for(int i=0; i<res.size(); i++) {
 
1169
      assertEquals(expected2.get(i), res.get(i));
 
1170
    }
 
1171
    
 
1172
  }
 
1173
  
 
1174
  public void testScanner_ExplicitColumns_FromMemStore_EnforceVersions() 
 
1175
  throws IOException {
 
1176
    byte [] tableName = Bytes.toBytes("testtable");
 
1177
    byte [] row1 = Bytes.toBytes("row1");
 
1178
    byte [] qf1 = Bytes.toBytes("qualifier1");
 
1179
    byte [] qf2 = Bytes.toBytes("qualifier2");
 
1180
    byte [] fam1 = Bytes.toBytes("fam1");
 
1181
    byte [][] families = {fam1};
 
1182
    
 
1183
    long ts1 = System.currentTimeMillis();
 
1184
    long ts2 = ts1 + 1;
 
1185
    long ts3 = ts1 + 2;
 
1186
    
 
1187
    //Setting up region
 
1188
    String method = this.getName();
 
1189
    initHRegion(tableName, method, families);
 
1190
    
 
1191
    //Putting data in Region
 
1192
    Put put = null;
 
1193
    KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);
 
1194
    KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);
 
1195
    KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);
 
1196
    
 
1197
    KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);
 
1198
    KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);
 
1199
    KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);
 
1200
    
 
1201
    put = new Put(row1);
 
1202
    put.add(kv13);
 
1203
    put.add(kv12);
 
1204
    put.add(kv11);
 
1205
    put.add(kv23);
 
1206
    put.add(kv22);
 
1207
    put.add(kv21);
 
1208
    region.put(put);
 
1209
    
 
1210
    //Expected
 
1211
    List<KeyValue> expected = new ArrayList<KeyValue>();
 
1212
    expected.add(kv13);
 
1213
    expected.add(kv12);
 
1214
    
 
1215
    Scan scan = new Scan(row1);
 
1216
    scan.addColumn(fam1, qf1);
 
1217
    scan.setMaxVersions(MAX_VERSIONS);
 
1218
    List<KeyValue> actual = new ArrayList<KeyValue>();
 
1219
    InternalScanner scanner = region.getScanner(scan);
 
1220
    
 
1221
    boolean hasNext = scanner.next(actual);
 
1222
    assertEquals(false, hasNext);
 
1223
    
 
1224
    //Verify result
 
1225
    for(int i=0; i<expected.size(); i++) {
 
1226
      assertEquals(expected.get(i), actual.get(i));
 
1227
    }
 
1228
  }
 
1229
  
 
1230
  public void testScanner_ExplicitColumns_FromFilesOnly_EnforceVersions() 
 
1231
  throws IOException{
 
1232
    byte [] tableName = Bytes.toBytes("testtable");
 
1233
    byte [] row1 = Bytes.toBytes("row1");
 
1234
    byte [] qf1 = Bytes.toBytes("qualifier1");
 
1235
    byte [] qf2 = Bytes.toBytes("qualifier2");
 
1236
    byte [] fam1 = Bytes.toBytes("fam1");
 
1237
    byte [][] families = {fam1};
 
1238
    
 
1239
    long ts1 = 1; //System.currentTimeMillis();
 
1240
    long ts2 = ts1 + 1;
 
1241
    long ts3 = ts1 + 2;
 
1242
    
 
1243
    //Setting up region
 
1244
    String method = this.getName();
 
1245
    initHRegion(tableName, method, families);
 
1246
    
 
1247
    //Putting data in Region
 
1248
    Put put = null;
 
1249
    KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);
 
1250
    KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);
 
1251
    KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);
 
1252
    
 
1253
    KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);
 
1254
    KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);
 
1255
    KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);
 
1256
    
 
1257
    put = new Put(row1);
 
1258
    put.add(kv13);
 
1259
    put.add(kv12);
 
1260
    put.add(kv11);
 
1261
    put.add(kv23);
 
1262
    put.add(kv22);
 
1263
    put.add(kv21);
 
1264
    region.put(put);
 
1265
    region.flushcache();
 
1266
    
 
1267
    //Expected
 
1268
    List<KeyValue> expected = new ArrayList<KeyValue>();
 
1269
    expected.add(kv13);
 
1270
    expected.add(kv12);
 
1271
    expected.add(kv23);
 
1272
    expected.add(kv22);
 
1273
    
 
1274
    Scan scan = new Scan(row1);
 
1275
    scan.addColumn(fam1, qf1);
 
1276
    scan.addColumn(fam1, qf2);
 
1277
    scan.setMaxVersions(MAX_VERSIONS);
 
1278
    List<KeyValue> actual = new ArrayList<KeyValue>();
 
1279
    InternalScanner scanner = region.getScanner(scan);
 
1280
    
 
1281
    boolean hasNext = scanner.next(actual);
 
1282
    assertEquals(false, hasNext);
 
1283
    
 
1284
    //Verify result
 
1285
    for(int i=0; i<expected.size(); i++) {
 
1286
      assertEquals(expected.get(i), actual.get(i));
 
1287
    }
 
1288
  }
 
1289
  
 
1290
  public void testScanner_ExplicitColumns_FromMemStoreAndFiles_EnforceVersions()
 
1291
  throws IOException {
 
1292
    byte [] tableName = Bytes.toBytes("testtable");
 
1293
    byte [] row1 = Bytes.toBytes("row1");
 
1294
    byte [] fam1 = Bytes.toBytes("fam1");
 
1295
    byte [][] families = {fam1};
 
1296
    byte [] qf1 = Bytes.toBytes("qualifier1");
 
1297
    byte [] qf2 = Bytes.toBytes("qualifier2");
 
1298
    
 
1299
    long ts1 = 1;
 
1300
    long ts2 = ts1 + 1;
 
1301
    long ts3 = ts1 + 2;
 
1302
    long ts4 = ts1 + 3;
 
1303
    
 
1304
    //Setting up region
 
1305
    String method = this.getName();
 
1306
    initHRegion(tableName, method, families);
 
1307
    
 
1308
    //Putting data in Region
 
1309
    KeyValue kv14 = new KeyValue(row1, fam1, qf1, ts4, KeyValue.Type.Put, null);
 
1310
    KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);
 
1311
    KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);
 
1312
    KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);
 
1313
    
 
1314
    KeyValue kv24 = new KeyValue(row1, fam1, qf2, ts4, KeyValue.Type.Put, null);
 
1315
    KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);
 
1316
    KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);
 
1317
    KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);
 
1318
    
 
1319
    Put put = null;
 
1320
    put = new Put(row1);
 
1321
    put.add(kv14);
 
1322
    put.add(kv24);
 
1323
    region.put(put);
 
1324
    region.flushcache();
 
1325
    
 
1326
    put = new Put(row1);
 
1327
    put.add(kv23);
 
1328
    put.add(kv13);
 
1329
    region.put(put);
 
1330
    region.flushcache();
 
1331
    
 
1332
    put = new Put(row1);
 
1333
    put.add(kv22);
 
1334
    put.add(kv12);
 
1335
    region.put(put);
 
1336
    region.flushcache();
 
1337
    
 
1338
    put = new Put(row1);
 
1339
    put.add(kv21);
 
1340
    put.add(kv11);
 
1341
    region.put(put);
 
1342
    
 
1343
    //Expected
 
1344
    List<KeyValue> expected = new ArrayList<KeyValue>();
 
1345
    expected.add(kv14);
 
1346
    expected.add(kv13);
 
1347
    expected.add(kv12);
 
1348
    expected.add(kv24);
 
1349
    expected.add(kv23);
 
1350
    expected.add(kv22);
 
1351
    
 
1352
    Scan scan = new Scan(row1);
 
1353
    scan.addColumn(fam1, qf1);
 
1354
    scan.addColumn(fam1, qf2);
 
1355
    int versions = 3;
 
1356
    scan.setMaxVersions(versions);
 
1357
    List<KeyValue> actual = new ArrayList<KeyValue>();
 
1358
    InternalScanner scanner = region.getScanner(scan);
 
1359
    
 
1360
    boolean hasNext = scanner.next(actual);
 
1361
    assertEquals(false, hasNext);
 
1362
    
 
1363
    //Verify result
 
1364
    for(int i=0; i<expected.size(); i++) {
 
1365
      assertEquals(expected.get(i), actual.get(i));
 
1366
    }
 
1367
  }
 
1368
  
 
1369
  public void testScanner_Wildcard_FromMemStore_EnforceVersions() 
 
1370
  throws IOException {
 
1371
    byte [] tableName = Bytes.toBytes("testtable");
 
1372
    byte [] row1 = Bytes.toBytes("row1");
 
1373
    byte [] qf1 = Bytes.toBytes("qualifier1");
 
1374
    byte [] qf2 = Bytes.toBytes("qualifier2");
 
1375
    byte [] fam1 = Bytes.toBytes("fam1");
 
1376
    byte [][] families = {fam1};
 
1377
    
 
1378
    long ts1 = System.currentTimeMillis();
 
1379
    long ts2 = ts1 + 1;
 
1380
    long ts3 = ts1 + 2;
 
1381
    
 
1382
    //Setting up region
 
1383
    String method = this.getName();
 
1384
    initHRegion(tableName, method, families);
 
1385
    
 
1386
    //Putting data in Region
 
1387
    Put put = null;
 
1388
    KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);
 
1389
    KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);
 
1390
    KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);
 
1391
    
 
1392
    KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);
 
1393
    KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);
 
1394
    KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);
 
1395
    
 
1396
    put = new Put(row1);
 
1397
    put.add(kv13);
 
1398
    put.add(kv12);
 
1399
    put.add(kv11);
 
1400
    put.add(kv23);
 
1401
    put.add(kv22);
 
1402
    put.add(kv21);
 
1403
    region.put(put);
 
1404
    
 
1405
    //Expected
 
1406
    List<KeyValue> expected = new ArrayList<KeyValue>();
 
1407
    expected.add(kv13);
 
1408
    expected.add(kv12);
 
1409
    expected.add(kv23);
 
1410
    expected.add(kv22);
 
1411
    
 
1412
    Scan scan = new Scan(row1);
 
1413
    scan.addFamily(fam1);
 
1414
    scan.setMaxVersions(MAX_VERSIONS);
 
1415
    List<KeyValue> actual = new ArrayList<KeyValue>();
 
1416
    InternalScanner scanner = region.getScanner(scan);
 
1417
    
 
1418
    boolean hasNext = scanner.next(actual);
 
1419
    assertEquals(false, hasNext);
 
1420
    
 
1421
    //Verify result
 
1422
    for(int i=0; i<expected.size(); i++) {
 
1423
      assertEquals(expected.get(i), actual.get(i));
 
1424
    }
 
1425
  }
 
1426
  
 
1427
  public void testScanner_Wildcard_FromFilesOnly_EnforceVersions() 
 
1428
  throws IOException{
 
1429
    byte [] tableName = Bytes.toBytes("testtable");
 
1430
    byte [] row1 = Bytes.toBytes("row1");
 
1431
    byte [] qf1 = Bytes.toBytes("qualifier1");
 
1432
    byte [] qf2 = Bytes.toBytes("qualifier2");
 
1433
    byte [] fam1 = Bytes.toBytes("fam1");
 
1434
 
 
1435
    long ts1 = 1; //System.currentTimeMillis();
 
1436
    long ts2 = ts1 + 1;
 
1437
    long ts3 = ts1 + 2;
 
1438
    
 
1439
    //Setting up region
 
1440
    String method = this.getName();
 
1441
    initHRegion(tableName, method, fam1);
 
1442
    
 
1443
    //Putting data in Region
 
1444
    Put put = null;
 
1445
    KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);
 
1446
    KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);
 
1447
    KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);
 
1448
    
 
1449
    KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);
 
1450
    KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);
 
1451
    KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);
 
1452
    
 
1453
    put = new Put(row1);
 
1454
    put.add(kv13);
 
1455
    put.add(kv12);
 
1456
    put.add(kv11);
 
1457
    put.add(kv23);
 
1458
    put.add(kv22);
 
1459
    put.add(kv21);
 
1460
    region.put(put);
 
1461
    region.flushcache();
 
1462
    
 
1463
    //Expected
 
1464
    List<KeyValue> expected = new ArrayList<KeyValue>();
 
1465
    expected.add(kv13);
 
1466
    expected.add(kv12);
 
1467
    expected.add(kv23);
 
1468
    expected.add(kv22);
 
1469
    
 
1470
    Scan scan = new Scan(row1);
 
1471
    scan.addFamily(fam1);
 
1472
    scan.setMaxVersions(MAX_VERSIONS);
 
1473
    List<KeyValue> actual = new ArrayList<KeyValue>();
 
1474
    InternalScanner scanner = region.getScanner(scan);
 
1475
    
 
1476
    boolean hasNext = scanner.next(actual);
 
1477
    assertEquals(false, hasNext);
 
1478
    
 
1479
    //Verify result
 
1480
    for(int i=0; i<expected.size(); i++) {
 
1481
      assertEquals(expected.get(i), actual.get(i));
 
1482
    }
 
1483
  }
 
1484
 
 
1485
  public void testScanner_StopRow1542() throws IOException {
 
1486
    byte [] tableName = Bytes.toBytes("test_table");
 
1487
    byte [] family = Bytes.toBytes("testFamily");
 
1488
    initHRegion(tableName, getName(), family);
 
1489
 
 
1490
    byte [] row1 = Bytes.toBytes("row111");
 
1491
    byte [] row2 = Bytes.toBytes("row222");
 
1492
    byte [] row3 = Bytes.toBytes("row333");
 
1493
    byte [] row4 = Bytes.toBytes("row444");
 
1494
    byte [] row5 = Bytes.toBytes("row555");
 
1495
 
 
1496
    byte [] col1 = Bytes.toBytes("Pub111");
 
1497
    byte [] col2 = Bytes.toBytes("Pub222");
 
1498
 
 
1499
 
 
1500
    Put put = new Put(row1);
 
1501
    put.add(family, col1, Bytes.toBytes(10L));
 
1502
    region.put(put);
 
1503
 
 
1504
    put = new Put(row2);
 
1505
    put.add(family, col1, Bytes.toBytes(15L));
 
1506
    region.put(put);
 
1507
 
 
1508
    put = new Put(row3);
 
1509
    put.add(family, col2, Bytes.toBytes(20L));
 
1510
    region.put(put);
 
1511
 
 
1512
    put = new Put(row4);
 
1513
    put.add(family, col2, Bytes.toBytes(30L));
 
1514
    region.put(put);
 
1515
 
 
1516
    put = new Put(row5);
 
1517
    put.add(family, col1, Bytes.toBytes(40L));
 
1518
    region.put(put);
 
1519
 
 
1520
    Scan scan = new Scan(row3, row4);
 
1521
    scan.setMaxVersions();
 
1522
    scan.addColumn(family, col1);
 
1523
    InternalScanner s = region.getScanner(scan);
 
1524
 
 
1525
    List<KeyValue> results = new ArrayList<KeyValue>();
 
1526
    assertEquals(false, s.next(results));
 
1527
    assertEquals(0, results.size());
 
1528
  }
 
1529
 
 
1530
  public void testIncrementColumnValue_UpdatingInPlace() throws IOException {
 
1531
    initHRegion(tableName, getName(), fam1);
 
1532
 
 
1533
    long value = 1L;
 
1534
    long amount = 3L;
 
1535
 
 
1536
    Put put = new Put(row);
 
1537
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1538
    region.put(put);
 
1539
 
 
1540
    long result = region.incrementColumnValue(row, fam1, qual1, amount, true);
 
1541
    
 
1542
    assertEquals(value+amount, result);
 
1543
 
 
1544
    Store store = region.getStore(fam1);
 
1545
    assertEquals(1, store.memstore.kvset.size());
 
1546
    assertTrue(store.memstore.snapshot.isEmpty());
 
1547
 
 
1548
    assertICV(row, fam1, qual1, value+amount);
 
1549
  }
 
1550
 
 
1551
  public void testIncrementColumnValue_BumpSnapshot() throws IOException {
 
1552
    initHRegion(tableName, getName(), fam1);
 
1553
 
 
1554
    long value = 42L;
 
1555
    long incr = 44L;
 
1556
 
 
1557
    // first put something in kvset, then snapshot it.
 
1558
    Put put = new Put(row);
 
1559
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1560
    region.put(put);
 
1561
 
 
1562
    // get the store in question:
 
1563
    Store s = region.getStore(fam1);
 
1564
    s.snapshot(); //bam
 
1565
 
 
1566
    // now increment:
 
1567
    long newVal = region.incrementColumnValue(row, fam1, qual1,
 
1568
        incr, false);
 
1569
 
 
1570
    assertEquals(value+incr, newVal);
 
1571
 
 
1572
    // get both versions:
 
1573
    Get get = new Get(row);
 
1574
    get.setMaxVersions();
 
1575
    get.addColumn(fam1,qual1);
 
1576
 
 
1577
    Result r = region.get(get, null);
 
1578
    assertEquals(2, r.size());
 
1579
    KeyValue first = r.raw()[0];
 
1580
    KeyValue second = r.raw()[1];
 
1581
 
 
1582
    assertTrue("ICV failed to upgrade timestamp",
 
1583
        first.getTimestamp() != second.getTimestamp());
 
1584
  }
 
1585
  
 
1586
  public void testIncrementColumnValue_ConcurrentFlush() throws IOException {
 
1587
    initHRegion(tableName, getName(), fam1);
 
1588
 
 
1589
    long value = 1L;
 
1590
    long amount = 3L;
 
1591
 
 
1592
    Put put = new Put(row);
 
1593
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1594
    region.put(put);
 
1595
 
 
1596
    // now increment during a flush
 
1597
    Thread t = new Thread() {
 
1598
      public void run() {
 
1599
        try {
 
1600
          region.flushcache();
 
1601
        } catch (IOException e) {
 
1602
          LOG.info("test ICV, got IOE during flushcache()");
 
1603
        }
 
1604
      }
 
1605
    };
 
1606
    t.start();
 
1607
    long r = region.incrementColumnValue(row, fam1, qual1, amount, true);
 
1608
    assertEquals(value+amount, r);
 
1609
 
 
1610
    // this also asserts there is only 1 KeyValue in the set.
 
1611
    assertICV(row, fam1, qual1, value+amount);
 
1612
  }
 
1613
 
 
1614
  public void testIncrementColumnValue_UpdatingInPlace_Negative()
 
1615
    throws IOException {
 
1616
    initHRegion(tableName, getName(), fam1);
 
1617
 
 
1618
    long value = 3L;
 
1619
    long amount = -1L;
 
1620
 
 
1621
    Put put = new Put(row);
 
1622
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1623
    region.put(put);
 
1624
 
 
1625
    long result = region.incrementColumnValue(row, fam1, qual1, amount, true);
 
1626
    assertEquals(value+amount, result);
 
1627
 
 
1628
    assertICV(row, fam1, qual1, value+amount);
 
1629
  }
 
1630
 
 
1631
  public void testIncrementColumnValue_AddingNew()
 
1632
    throws IOException {
 
1633
    initHRegion(tableName, getName(), fam1);
 
1634
 
 
1635
    long value = 1L;
 
1636
    long amount = 3L;
 
1637
 
 
1638
    Put put = new Put(row);
 
1639
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1640
    put.add(fam1, qual2, Bytes.toBytes(value));
 
1641
    region.put(put);
 
1642
 
 
1643
    long result = region.incrementColumnValue(row, fam1, qual3, amount, true);
 
1644
    assertEquals(amount, result);
 
1645
 
 
1646
    Get get = new Get(row);
 
1647
    get.addColumn(fam1, qual3);
 
1648
    Result rr = region.get(get, null);
 
1649
    assertEquals(1, rr.size());
 
1650
 
 
1651
    // ensure none of the other cols were incremented.
 
1652
    assertICV(row, fam1, qual1, value);
 
1653
    assertICV(row, fam1, qual2, value);
 
1654
    assertICV(row, fam1, qual3, amount);
 
1655
  }
 
1656
 
 
1657
  public void testIncrementColumnValue_UpdatingFromSF() throws IOException {
 
1658
    initHRegion(tableName, getName(), fam1);
 
1659
 
 
1660
    long value = 1L;
 
1661
    long amount = 3L;
 
1662
 
 
1663
    Put put = new Put(row);
 
1664
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1665
    put.add(fam1, qual2, Bytes.toBytes(value));
 
1666
    region.put(put);
 
1667
 
 
1668
    // flush to disk.
 
1669
    region.flushcache();
 
1670
 
 
1671
    Store store = region.getStore(fam1);
 
1672
    assertEquals(0, store.memstore.kvset.size());
 
1673
 
 
1674
    long r = region.incrementColumnValue(row, fam1, qual1, amount, true);
 
1675
    assertEquals(value+amount, r);
 
1676
 
 
1677
    assertICV(row, fam1, qual1, value+amount);
 
1678
  }
 
1679
 
 
1680
  public void testIncrementColumnValue_AddingNewAfterSFCheck()
 
1681
    throws IOException {
 
1682
    initHRegion(tableName, getName(), fam1);
 
1683
 
 
1684
    long value = 1L;
 
1685
    long amount = 3L;
 
1686
 
 
1687
    Put put = new Put(row);
 
1688
    put.add(fam1, qual1, Bytes.toBytes(value));
 
1689
    put.add(fam1, qual2, Bytes.toBytes(value));
 
1690
    region.put(put);
 
1691
    region.flushcache();
 
1692
 
 
1693
    Store store = region.getStore(fam1);
 
1694
    assertEquals(0, store.memstore.kvset.size());
 
1695
 
 
1696
    long r = region.incrementColumnValue(row, fam1, qual3, amount, true);
 
1697
    assertEquals(amount, r);
 
1698
 
 
1699
    assertICV(row, fam1, qual3, amount);
 
1700
 
 
1701
    region.flushcache();
 
1702
 
 
1703
    // ensure that this gets to disk.
 
1704
    assertICV(row, fam1, qual3, amount);
 
1705
  }
 
1706
 
 
1707
  private void assertICV(byte [] row,
 
1708
                         byte [] familiy,
 
1709
                         byte[] qualifier,
 
1710
                         long amount) throws IOException {
 
1711
    // run a get and see?
 
1712
    Get get = new Get(row);
 
1713
    get.addColumn(familiy, qualifier);
 
1714
    Result result = region.get(get, null);
 
1715
    assertEquals(1, result.size());
 
1716
 
 
1717
    KeyValue kv = result.raw()[0];
 
1718
    long r = Bytes.toLong(kv.getValue());
 
1719
    assertEquals(amount, r);
 
1720
  }
 
1721
 
 
1722
 
 
1723
  
 
1724
  public void testScanner_Wildcard_FromMemStoreAndFiles_EnforceVersions()
 
1725
  throws IOException {
 
1726
    byte [] tableName = Bytes.toBytes("testtable");
 
1727
    byte [] row1 = Bytes.toBytes("row1");
 
1728
    byte [] fam1 = Bytes.toBytes("fam1");
 
1729
    byte [] qf1 = Bytes.toBytes("qualifier1");
 
1730
    byte [] qf2 = Bytes.toBytes("quateslifier2");
 
1731
    
 
1732
    long ts1 = 1;
 
1733
    long ts2 = ts1 + 1;
 
1734
    long ts3 = ts1 + 2;
 
1735
    long ts4 = ts1 + 3;
 
1736
    
 
1737
    //Setting up region
 
1738
    String method = this.getName();
 
1739
    initHRegion(tableName, method, fam1);
 
1740
    
 
1741
    //Putting data in Region
 
1742
    KeyValue kv14 = new KeyValue(row1, fam1, qf1, ts4, KeyValue.Type.Put, null);
 
1743
    KeyValue kv13 = new KeyValue(row1, fam1, qf1, ts3, KeyValue.Type.Put, null);
 
1744
    KeyValue kv12 = new KeyValue(row1, fam1, qf1, ts2, KeyValue.Type.Put, null);
 
1745
    KeyValue kv11 = new KeyValue(row1, fam1, qf1, ts1, KeyValue.Type.Put, null);
 
1746
    
 
1747
    KeyValue kv24 = new KeyValue(row1, fam1, qf2, ts4, KeyValue.Type.Put, null);
 
1748
    KeyValue kv23 = new KeyValue(row1, fam1, qf2, ts3, KeyValue.Type.Put, null);
 
1749
    KeyValue kv22 = new KeyValue(row1, fam1, qf2, ts2, KeyValue.Type.Put, null);
 
1750
    KeyValue kv21 = new KeyValue(row1, fam1, qf2, ts1, KeyValue.Type.Put, null);
 
1751
    
 
1752
    Put put = null;
 
1753
    put = new Put(row1);
 
1754
    put.add(kv14);
 
1755
    put.add(kv24);
 
1756
    region.put(put);
 
1757
    region.flushcache();
 
1758
    
 
1759
    put = new Put(row1);
 
1760
    put.add(kv23);
 
1761
    put.add(kv13);
 
1762
    region.put(put);
 
1763
    region.flushcache();
 
1764
    
 
1765
    put = new Put(row1);
 
1766
    put.add(kv22);
 
1767
    put.add(kv12);
 
1768
    region.put(put);
 
1769
    region.flushcache();
 
1770
    
 
1771
    put = new Put(row1);
 
1772
    put.add(kv21);
 
1773
    put.add(kv11);
 
1774
    region.put(put);
 
1775
    
 
1776
    //Expected
 
1777
    List<KeyValue> expected = new ArrayList<KeyValue>();
 
1778
    expected.add(kv14);
 
1779
    expected.add(kv13);
 
1780
    expected.add(kv12);
 
1781
    expected.add(kv24);
 
1782
    expected.add(kv23);
 
1783
    expected.add(kv22);
 
1784
    
 
1785
    Scan scan = new Scan(row1);
 
1786
    int versions = 3;
 
1787
    scan.setMaxVersions(versions);
 
1788
    List<KeyValue> actual = new ArrayList<KeyValue>();
 
1789
    InternalScanner scanner = region.getScanner(scan);
 
1790
    
 
1791
    boolean hasNext = scanner.next(actual);
 
1792
    assertEquals(false, hasNext);
 
1793
    
 
1794
    //Verify result
 
1795
    for(int i=0; i<expected.size(); i++) {
 
1796
      assertEquals(expected.get(i), actual.get(i));
 
1797
    }
 
1798
  }
 
1799
 
 
1800
  //////////////////////////////////////////////////////////////////////////////
 
1801
  // Split test
 
1802
  //////////////////////////////////////////////////////////////////////////////
 
1803
  /**
 
1804
   * Splits twice and verifies getting from each of the split regions.
 
1805
   * @throws Exception
 
1806
   */
 
1807
  public void testBasicSplit() throws Exception {
 
1808
    byte [] tableName = Bytes.toBytes("testtable");
 
1809
    byte [][] families = {fam1, fam2, fam3};
 
1810
    
 
1811
    HBaseConfiguration hc = initSplit();
 
1812
    //Setting up region
 
1813
    String method = this.getName();
 
1814
    initHRegion(tableName, method, hc, families);
 
1815
    
 
1816
    try {
 
1817
      LOG.info("" + addContent(region, fam3));
 
1818
      region.flushcache();
 
1819
      byte [] splitRow = region.compactStores();
 
1820
      assertNotNull(splitRow);
 
1821
      LOG.info("SplitRow: " + Bytes.toString(splitRow));
 
1822
      HRegion [] regions = split(region, splitRow);
 
1823
      try {
 
1824
        // Need to open the regions.
 
1825
        // TODO: Add an 'open' to HRegion... don't do open by constructing
 
1826
        // instance.
 
1827
        for (int i = 0; i < regions.length; i++) {
 
1828
          regions[i] = openClosedRegion(regions[i]);
 
1829
        }
 
1830
        // Assert can get rows out of new regions. Should be able to get first
 
1831
        // row from first region and the midkey from second region.
 
1832
        assertGet(regions[0], fam3, Bytes.toBytes(START_KEY));
 
1833
        assertGet(regions[1], fam3, splitRow);
 
1834
        // Test I can get scanner and that it starts at right place.
 
1835
        assertScan(regions[0], fam3,
 
1836
            Bytes.toBytes(START_KEY));
 
1837
        assertScan(regions[1], fam3, splitRow);
 
1838
        // Now prove can't split regions that have references.
 
1839
        for (int i = 0; i < regions.length; i++) {
 
1840
          // Add so much data to this region, we create a store file that is >
 
1841
          // than one of our unsplitable references. it will.
 
1842
          for (int j = 0; j < 2; j++) {
 
1843
            addContent(regions[i], fam3);
 
1844
          }
 
1845
          addContent(regions[i], fam2);
 
1846
          addContent(regions[i], fam1);
 
1847
          regions[i].flushcache();
 
1848
        }
 
1849
 
 
1850
        byte [][] midkeys = new byte [regions.length][];
 
1851
        // To make regions splitable force compaction.
 
1852
        for (int i = 0; i < regions.length; i++) {
 
1853
          midkeys[i] = regions[i].compactStores();
 
1854
        }
 
1855
 
 
1856
        TreeMap<String, HRegion> sortedMap = new TreeMap<String, HRegion>();
 
1857
        // Split these two daughter regions so then I'll have 4 regions. Will
 
1858
        // split because added data above.
 
1859
        for (int i = 0; i < regions.length; i++) {
 
1860
          HRegion[] rs = null;
 
1861
          if (midkeys[i] != null) {
 
1862
            rs = split(regions[i], midkeys[i]);
 
1863
            for (int j = 0; j < rs.length; j++) {
 
1864
              sortedMap.put(Bytes.toString(rs[j].getRegionName()),
 
1865
                openClosedRegion(rs[j]));
 
1866
            }
 
1867
          }
 
1868
        }
 
1869
        LOG.info("Made 4 regions");
 
1870
        // The splits should have been even. Test I can get some arbitrary row
 
1871
        // out of each.
 
1872
        int interval = (LAST_CHAR - FIRST_CHAR) / 3;
 
1873
        byte[] b = Bytes.toBytes(START_KEY);
 
1874
        for (HRegion r : sortedMap.values()) {
 
1875
          assertGet(r, fam3, b);
 
1876
          b[0] += interval;
 
1877
        }
 
1878
      } finally {
 
1879
        for (int i = 0; i < regions.length; i++) {
 
1880
          try {
 
1881
            regions[i].close();
 
1882
          } catch (IOException e) {
 
1883
            // Ignore.
 
1884
          }
 
1885
        }
 
1886
      }
 
1887
    } finally {
 
1888
      if (region != null) {
 
1889
        region.close();
 
1890
        region.getLog().closeAndDelete();
 
1891
      }
 
1892
    }
 
1893
  }
 
1894
  
 
1895
  public void testSplitRegion() throws IOException {
 
1896
    byte [] tableName = Bytes.toBytes("testtable");
 
1897
    byte [] qualifier = Bytes.toBytes("qualifier");
 
1898
    HBaseConfiguration hc = initSplit();
 
1899
    int numRows = 10;
 
1900
    byte [][] families = {fam1, fam3};
 
1901
    
 
1902
    //Setting up region
 
1903
    String method = this.getName();
 
1904
    initHRegion(tableName, method, hc, families);
 
1905
 
 
1906
    //Put data in region
 
1907
    int startRow = 100;
 
1908
    putData(startRow, numRows, qualifier, families);
 
1909
    int splitRow = startRow + numRows;
 
1910
    putData(splitRow, numRows, qualifier, families);
 
1911
    region.flushcache();
 
1912
    
 
1913
    HRegion [] regions = null;
 
1914
    try {
 
1915
      regions = region.splitRegion(Bytes.toBytes("" + splitRow));
 
1916
      //Opening the regions returned. 
 
1917
      for (int i = 0; i < regions.length; i++) {
 
1918
        regions[i] = openClosedRegion(regions[i]);
 
1919
      }
 
1920
      //Verifying that the region has been split
 
1921
      assertEquals(2, regions.length);
 
1922
      
 
1923
      //Verifying that all data is still there and that data is in the right
 
1924
      //place
 
1925
      verifyData(regions[0], startRow, numRows, qualifier, families);
 
1926
      verifyData(regions[1], splitRow, numRows, qualifier, families);
 
1927
      
 
1928
    } finally {
 
1929
      if (region != null) {
 
1930
        region.close();
 
1931
        region.getLog().closeAndDelete();
 
1932
      }
 
1933
    }
 
1934
  }
 
1935
 
 
1936
  /**
 
1937
   * Flushes the cache in a thread while scanning. The tests verify that the
 
1938
   * scan is coherent - e.g. the returned results are always of the same or
 
1939
   * later update as the previous results.
 
1940
   * @throws IOException scan / compact
 
1941
   * @throws InterruptedException thread join
 
1942
   */
 
1943
  public void testFlushCacheWhileScanning() throws IOException, InterruptedException {
 
1944
    byte[] tableName = Bytes.toBytes("testFlushCacheWhileScanning");
 
1945
    byte[] family = Bytes.toBytes("family");
 
1946
    int numRows = 1000;
 
1947
    int flushAndScanInterval = 10;
 
1948
    int compactInterval = 10 * flushAndScanInterval;
 
1949
 
 
1950
    String method = "testFlushCacheWhileScanning";
 
1951
    initHRegion(tableName,method, family);
 
1952
    FlushThread flushThread = new FlushThread();
 
1953
    flushThread.start();
 
1954
 
 
1955
    Scan scan = new Scan();
 
1956
    scan.addFamily(family);
 
1957
    scan.setFilter(new SingleColumnValueFilter(family, qual1,
 
1958
      CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(5L))));
 
1959
 
 
1960
    int expectedCount = 0;
 
1961
    List<KeyValue> res = new ArrayList<KeyValue>();
 
1962
 
 
1963
    boolean toggle=true;
 
1964
    for (long i = 0; i < numRows; i++) {
 
1965
      Put put = new Put(Bytes.toBytes(i));
 
1966
      put.add(family, qual1, Bytes.toBytes(i % 10));
 
1967
      region.put(put);
 
1968
 
 
1969
      if (i != 0 && i % compactInterval == 0) {
 
1970
        //System.out.println("iteration = " + i);
 
1971
        region.compactStores(true);
 
1972
      }
 
1973
 
 
1974
      if (i % 10 == 5L) {
 
1975
        expectedCount++;
 
1976
      }
 
1977
 
 
1978
      if (i != 0 && i % flushAndScanInterval == 0) {
 
1979
        res.clear();
 
1980
        InternalScanner scanner = region.getScanner(scan);
 
1981
        if (toggle) {
 
1982
          flushThread.flush();
 
1983
        }
 
1984
        while (scanner.next(res)) ;
 
1985
        if (!toggle) {
 
1986
          flushThread.flush();
 
1987
        }
 
1988
        Assert.assertEquals("i=" + i, expectedCount, res.size());
 
1989
        toggle = !toggle;
 
1990
      }
 
1991
    }
 
1992
 
 
1993
    flushThread.done();
 
1994
    flushThread.join();
 
1995
    flushThread.checkNoError();
 
1996
  }
 
1997
 
 
1998
  protected class FlushThread extends Thread {
 
1999
    private volatile boolean done;
 
2000
    private Throwable error = null;
 
2001
 
 
2002
    public void done() {
 
2003
      done = true;
 
2004
      synchronized (this) {
 
2005
        interrupt();
 
2006
      }
 
2007
    }
 
2008
 
 
2009
    public void checkNoError() {
 
2010
      if (error != null) {
 
2011
        Assert.assertNull(error);
 
2012
      }
 
2013
    }
 
2014
 
 
2015
    @Override
 
2016
    public void run() {
 
2017
      done = false;
 
2018
      while (!done) {
 
2019
        synchronized (this) {
 
2020
          try {
 
2021
            wait();
 
2022
          } catch (InterruptedException ignored) {
 
2023
            if (done) {
 
2024
              break;
 
2025
            }
 
2026
          }
 
2027
        }
 
2028
        try {
 
2029
          region.flushcache();
 
2030
        } catch (IOException e) {
 
2031
          if (!done) {
 
2032
            LOG.error("Error while flusing cache", e);
 
2033
            error = e;
 
2034
          }
 
2035
          break;
 
2036
        }
 
2037
      }
 
2038
 
 
2039
    }
 
2040
 
 
2041
    public void flush() {
 
2042
      synchronized (this) {
 
2043
        notify();
 
2044
      }
 
2045
 
 
2046
    }
 
2047
  }
 
2048
 
 
2049
  /**
 
2050
   * Writes very wide records and scans for the latest every time..
 
2051
   * Flushes and compacts the region every now and then to keep things
 
2052
   * realistic.
 
2053
   *
 
2054
   * @throws IOException          by flush / scan / compaction
 
2055
   * @throws InterruptedException when joining threads
 
2056
   */
 
2057
  public void testWritesWhileScanning()
 
2058
    throws IOException, InterruptedException {
 
2059
    byte[] tableName = Bytes.toBytes("testWritesWhileScanning");
 
2060
    int testCount = 100;
 
2061
    int numRows = 1;
 
2062
    int numFamilies = 10;
 
2063
    int numQualifiers = 100;
 
2064
    int flushInterval = 7;
 
2065
    int compactInterval = 5 * flushInterval;
 
2066
    byte[][] families = new byte[numFamilies][];
 
2067
    for (int i = 0; i < numFamilies; i++) {
 
2068
      families[i] = Bytes.toBytes("family" + i);
 
2069
    }
 
2070
    byte[][] qualifiers = new byte[numQualifiers][];
 
2071
    for (int i = 0; i < numQualifiers; i++) {
 
2072
      qualifiers[i] = Bytes.toBytes("qual" + i);
 
2073
    }
 
2074
 
 
2075
    String method = "testWritesWhileScanning";
 
2076
    initHRegion(tableName, method, families);
 
2077
    PutThread putThread = new PutThread(numRows, families, qualifiers);
 
2078
    putThread.start();
 
2079
    FlushThread flushThread = new FlushThread();
 
2080
    flushThread.start();
 
2081
 
 
2082
    Scan scan = new Scan();
 
2083
    scan.setFilter(new RowFilter(CompareFilter.CompareOp.EQUAL,
 
2084
      new BinaryComparator(Bytes.toBytes("row0"))));
 
2085
 
 
2086
    int expectedCount = numFamilies * numQualifiers;
 
2087
    List<KeyValue> res = new ArrayList<KeyValue>();
 
2088
 
 
2089
    long prevTimestamp = 0L;
 
2090
    for (int i = 0; i < testCount; i++) {
 
2091
 
 
2092
      if (i != 0 && i % compactInterval == 0) {
 
2093
        region.compactStores(true);
 
2094
      }
 
2095
 
 
2096
      if (i != 0 && i % flushInterval == 0) {
 
2097
        //System.out.println("flush scan iteration = " + i);
 
2098
        flushThread.flush();
 
2099
      }
 
2100
 
 
2101
      boolean previousEmpty = res.isEmpty();
 
2102
      res.clear();
 
2103
      InternalScanner scanner = region.getScanner(scan);
 
2104
      while (scanner.next(res)) ;
 
2105
      if (!res.isEmpty() || !previousEmpty || i > compactInterval) {
 
2106
        assertEquals("i=" + i, expectedCount, res.size());
 
2107
        long timestamp = res.get(0).getTimestamp();
 
2108
        assertTrue("Timestamps were broke: " + timestamp + " prev: " + prevTimestamp,
 
2109
            timestamp >= prevTimestamp);
 
2110
        prevTimestamp = timestamp;
 
2111
      }
 
2112
    }
 
2113
 
 
2114
    putThread.done();
 
2115
    putThread.join();
 
2116
    putThread.checkNoError();
 
2117
 
 
2118
    flushThread.done();
 
2119
    flushThread.join();
 
2120
    flushThread.checkNoError();
 
2121
  }
 
2122
 
 
2123
  protected class PutThread extends Thread {
 
2124
    private final AtomicBoolean done = new AtomicBoolean(false);
 
2125
    private Throwable error = null;
 
2126
    private int numRows;
 
2127
    private byte[][] families;
 
2128
    private byte[][] qualifiers;
 
2129
 
 
2130
    private PutThread(int numRows, byte[][] families,
 
2131
      byte[][] qualifiers) {
 
2132
      this.numRows = numRows;
 
2133
      this.families = families;
 
2134
      this.qualifiers = qualifiers;
 
2135
    }
 
2136
 
 
2137
    public void done() {
 
2138
      done.set(true);
 
2139
    }
 
2140
 
 
2141
    public void checkNoError() {
 
2142
      if (error != null) {
 
2143
        Assert.assertNull(error);
 
2144
      }
 
2145
    }
 
2146
 
 
2147
    @Override
 
2148
    public void run() {
 
2149
      done.set(false);
 
2150
      int val = 0;
 
2151
      while (!done.get()) {
 
2152
        try {
 
2153
          for (int r = 0; r < numRows; r++) {
 
2154
            byte[] row = Bytes.toBytes("row" + r);
 
2155
            Put put = new Put(row);
 
2156
            for (byte[] family : families) {
 
2157
              for (byte[] qualifier : qualifiers) {
 
2158
                put.add(family, qualifier, (long) val,
 
2159
                    Bytes.toBytes(val));
 
2160
              }
 
2161
            }
 
2162
//            System.out.println("Putting of kvsetsize=" + put.size());
 
2163
            region.put(put);
 
2164
            if (val > 0 && val % 47 == 0) {
 
2165
              System.out.println("put iteration = " + val);
 
2166
              Delete delete = new Delete(row, (long)val-30, null);
 
2167
              region.delete(delete, null, true);
 
2168
            }
 
2169
            val++;
 
2170
          }
 
2171
        } catch (IOException e) {
 
2172
          LOG.error("error while putting records", e);
 
2173
          error = e;
 
2174
          break;
 
2175
        }
 
2176
      }
 
2177
 
 
2178
    }
 
2179
 
 
2180
  }
 
2181
 
 
2182
 
 
2183
  /**
 
2184
   * Writes very wide records and gets the latest row every time..
 
2185
   * Flushes and compacts the region every now and then to keep things
 
2186
   * realistic.
 
2187
   *
 
2188
   * @throws IOException          by flush / scan / compaction
 
2189
   * @throws InterruptedException when joining threads
 
2190
   */
 
2191
  public void testWritesWhileGetting()
 
2192
    throws IOException, InterruptedException {
 
2193
    byte[] tableName = Bytes.toBytes("testWritesWhileScanning");
 
2194
    int testCount = 100;
 
2195
    int numRows = 1;
 
2196
    int numFamilies = 10;
 
2197
    int numQualifiers = 100;
 
2198
    int flushInterval = 10;
 
2199
    int compactInterval = 10 * flushInterval;
 
2200
    byte[][] families = new byte[numFamilies][];
 
2201
    for (int i = 0; i < numFamilies; i++) {
 
2202
      families[i] = Bytes.toBytes("family" + i);
 
2203
    }
 
2204
    byte[][] qualifiers = new byte[numQualifiers][];
 
2205
    for (int i = 0; i < numQualifiers; i++) {
 
2206
      qualifiers[i] = Bytes.toBytes("qual" + i);
 
2207
    }
 
2208
 
 
2209
    String method = "testWritesWhileScanning";
 
2210
    initHRegion(tableName, method, families);
 
2211
    PutThread putThread = new PutThread(numRows, families, qualifiers);
 
2212
    putThread.start();
 
2213
    FlushThread flushThread = new FlushThread();
 
2214
    flushThread.start();
 
2215
 
 
2216
    Get get = new Get(Bytes.toBytes("row0"));
 
2217
    Result result = null;
 
2218
 
 
2219
    int expectedCount = numFamilies * numQualifiers;
 
2220
 
 
2221
    long prevTimestamp = 0L;
 
2222
    for (int i = 0; i < testCount; i++) {
 
2223
 
 
2224
      if (i != 0 && i % compactInterval == 0) {
 
2225
        region.compactStores(true);
 
2226
      }
 
2227
 
 
2228
      if (i != 0 && i % flushInterval == 0) {
 
2229
        System.out.println("iteration = " + i);
 
2230
        flushThread.flush();
 
2231
      }
 
2232
 
 
2233
      boolean previousEmpty = result == null || result.isEmpty();
 
2234
      result = region.get(get, null);
 
2235
      if (!result.isEmpty() || !previousEmpty || i > compactInterval) {
 
2236
        Assert.assertEquals("i=" + i, expectedCount, result.size());
 
2237
        long timestamp =
 
2238
          result.getCellValue(families[0], qualifiers[0]).getTimestamp();
 
2239
        Assert.assertTrue(timestamp >= prevTimestamp);
 
2240
        prevTimestamp = timestamp;
 
2241
 
 
2242
        byte [] gotValue = null;
 
2243
        for (KeyValue kv : result.raw()) {
 
2244
          byte [] thisValue = kv.getValue();
 
2245
          if (gotValue != null) {
 
2246
            assertEquals(gotValue, thisValue);
 
2247
          }
 
2248
          gotValue = thisValue;
 
2249
        }
 
2250
      }
 
2251
    }
 
2252
 
 
2253
    putThread.done();
 
2254
    putThread.join();
 
2255
    putThread.checkNoError();
 
2256
 
 
2257
    flushThread.done();
 
2258
    flushThread.join();
 
2259
    flushThread.checkNoError();
 
2260
  }
 
2261
 
 
2262
 
 
2263
  public void testIndexesScanWithOneDeletedRow() throws IOException {
 
2264
    byte[] tableName = Bytes.toBytes("testIndexesScanWithOneDeletedRow");
 
2265
    byte[] family = Bytes.toBytes("family");
 
2266
 
 
2267
    //Setting up region
 
2268
    String method = "testIndexesScanWithOneDeletedRow";
 
2269
    initHRegion(tableName, method, new HBaseConfiguration(), family);
 
2270
 
 
2271
    Put put = new Put(Bytes.toBytes(1L));
 
2272
    put.add(family, qual1, 1L, Bytes.toBytes(1L));
 
2273
    region.put(put);
 
2274
 
 
2275
    region.flushcache();
 
2276
 
 
2277
    Delete delete = new Delete(Bytes.toBytes(1L), 1L, null);
 
2278
    //delete.deleteColumn(family, qual1);
 
2279
    region.delete(delete, null, true);
 
2280
 
 
2281
    put = new Put(Bytes.toBytes(2L));
 
2282
    put.add(family, qual1, 2L, Bytes.toBytes(2L));
 
2283
    region.put(put);
 
2284
 
 
2285
    Scan idxScan = new Scan();
 
2286
    idxScan.addFamily(family);
 
2287
    idxScan.setFilter(new FilterList(FilterList.Operator.MUST_PASS_ALL,
 
2288
      Arrays.<Filter>asList(new SingleColumnValueFilter(family, qual1,
 
2289
        CompareFilter.CompareOp.GREATER_OR_EQUAL,
 
2290
        new BinaryComparator(Bytes.toBytes(0L))),
 
2291
        new SingleColumnValueFilter(family, qual1,
 
2292
          CompareFilter.CompareOp.LESS_OR_EQUAL,
 
2293
          new BinaryComparator(Bytes.toBytes(3L)))
 
2294
      )));
 
2295
    InternalScanner scanner = region.getScanner(idxScan);
 
2296
    List<KeyValue> res = new ArrayList<KeyValue>();
 
2297
 
 
2298
    //long start = System.nanoTime();
 
2299
    while (scanner.next(res)) ;
 
2300
    //long end = System.nanoTime();
 
2301
    //System.out.println("memStoreEmpty=" + memStoreEmpty + ", time=" + (end - start)/1000000D);
 
2302
    assertEquals(1L, res.size());
 
2303
 
 
2304
  }
 
2305
 
 
2306
 
 
2307
  private void putData(int startRow, int numRows, byte [] qf,
 
2308
      byte [] ...families)
 
2309
  throws IOException {
 
2310
    for(int i=startRow; i<startRow+numRows; i++) {
 
2311
      Put put = new Put(Bytes.toBytes("" + i));
 
2312
      for(byte [] family : families) {
 
2313
        put.add(family, qf, null);
 
2314
      }
 
2315
      region.put(put);
 
2316
    }
 
2317
  }
 
2318
 
 
2319
  private void verifyData(HRegion newReg, int startRow, int numRows, byte [] qf,
 
2320
      byte [] ... families) 
 
2321
  throws IOException {
 
2322
    for(int i=startRow; i<startRow + numRows; i++) {
 
2323
      byte [] row = Bytes.toBytes("" + i);
 
2324
      Get get = new Get(row);
 
2325
      for(byte [] family : families) {
 
2326
        get.addColumn(family, qf);
 
2327
      }
 
2328
      Result result = newReg.get(get, null);
 
2329
      KeyValue [] raw = result.sorted();
 
2330
      assertEquals(families.length, result.size());
 
2331
      for(int j=0; j<families.length; j++) {
 
2332
        assertEquals(0, Bytes.compareTo(row, raw[j].getRow()));
 
2333
        assertEquals(0, Bytes.compareTo(families[j], raw[j].getFamily()));
 
2334
        assertEquals(0, Bytes.compareTo(qf, raw[j].getQualifier()));
 
2335
      }
 
2336
    }
 
2337
  }
 
2338
 
 
2339
  private void assertGet(final HRegion r, final byte [] family, final byte [] k)
 
2340
  throws IOException {
 
2341
    // Now I have k, get values out and assert they are as expected.
 
2342
    Get get = new Get(k).addFamily(family).setMaxVersions();
 
2343
    KeyValue [] results = r.get(get, null).raw();
 
2344
    for (int j = 0; j < results.length; j++) {
 
2345
      byte [] tmp = results[j].getValue();
 
2346
      // Row should be equal to value every time.
 
2347
      assertTrue(Bytes.equals(k, tmp));
 
2348
    }
 
2349
  }
 
2350
  
 
2351
  /*
 
2352
   * Assert first value in the passed region is <code>firstValue</code>.
 
2353
   * @param r
 
2354
   * @param fs
 
2355
   * @param firstValue
 
2356
   * @throws IOException
 
2357
   */
 
2358
  private void assertScan(final HRegion r, final byte [] fs,
 
2359
      final byte [] firstValue)
 
2360
  throws IOException {
 
2361
    byte [][] families = {fs};
 
2362
    Scan scan = new Scan();
 
2363
    for (int i = 0; i < families.length; i++) scan.addFamily(families[i]);
 
2364
    InternalScanner s = r.getScanner(scan);
 
2365
    try {
 
2366
      List<KeyValue> curVals = new ArrayList<KeyValue>();
 
2367
      boolean first = true;
 
2368
      OUTER_LOOP: while(s.next(curVals)) {
 
2369
        for (KeyValue kv: curVals) {
 
2370
          byte [] val = kv.getValue();
 
2371
          byte [] curval = val;
 
2372
          if (first) {
 
2373
            first = false;
 
2374
            assertTrue(Bytes.compareTo(curval, firstValue) == 0);
 
2375
          } else {
 
2376
            // Not asserting anything.  Might as well break.
 
2377
            break OUTER_LOOP;
 
2378
          }
 
2379
        }
 
2380
      }
 
2381
    } finally {
 
2382
      s.close();
 
2383
    }
 
2384
  }
 
2385
  
 
2386
  protected HRegion [] split(final HRegion r, final byte [] splitRow)
 
2387
  throws IOException {
 
2388
    // Assert can get mid key from passed region.
 
2389
    assertGet(r, fam3, splitRow);
 
2390
    HRegion [] regions = r.splitRegion(splitRow);
 
2391
    assertEquals(regions.length, 2);
 
2392
    return regions;
 
2393
  }
 
2394
  
 
2395
  private HBaseConfiguration initSplit() {
 
2396
    HBaseConfiguration conf = new HBaseConfiguration();
 
2397
    // Always compact if there is more than one store file.
 
2398
    conf.setInt("hbase.hstore.compactionThreshold", 2);
 
2399
    
 
2400
    // Make lease timeout longer, lease checks less frequent
 
2401
    conf.setInt("hbase.master.lease.period", 10 * 1000);
 
2402
    conf.setInt("hbase.master.lease.thread.wakefrequency", 5 * 1000);
 
2403
    
 
2404
    conf.setInt("hbase.regionserver.lease.period", 10 * 1000);
 
2405
    
 
2406
    // Increase the amount of time between client retries
 
2407
    conf.setLong("hbase.client.pause", 15 * 1000);
 
2408
 
 
2409
    // This size should make it so we always split using the addContent
 
2410
    // below.  After adding all data, the first region is 1.3M
 
2411
    conf.setLong("hbase.hregion.max.filesize", 1024 * 128);
 
2412
    return conf;
 
2413
  }  
 
2414
 
 
2415
  private void initHRegion (byte [] tableName, String callingMethod,
 
2416
    byte[] ... families)
 
2417
  throws IOException {
 
2418
    initHRegion(tableName, callingMethod, new HBaseConfiguration(), families);
 
2419
  }
 
2420
 
 
2421
  protected void initHRegion(byte[] tableName, String callingMethod,
 
2422
    HBaseConfiguration conf, byte[]... families)
 
2423
    throws IOException {
 
2424
    HTableDescriptor htd = constructTableDescriptor(tableName, families);
 
2425
    HRegionInfo info = new HRegionInfo(htd, null, null, false);
 
2426
    Path path = new Path(DIR + callingMethod);
 
2427
    region = HRegion.createHRegion(info, path, conf);
 
2428
  }
 
2429
 
 
2430
  protected HTableDescriptor constructTableDescriptor(byte[] tableName,
 
2431
    byte[]... families) {
 
2432
    HTableDescriptor htd = new HTableDescriptor(tableName);
 
2433
    for (byte[] family : families) {
 
2434
      htd.addFamily(new HColumnDescriptor(family));
 
2435
    }
 
2436
    return htd;
 
2437
  }
 
2438
}