1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.mapreduce;
19
20 import static org.junit.Assert.assertEquals;
21
22 import java.util.Arrays;
23
24 import org.apache.commons.lang.ArrayUtils;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.fs.FileSystem;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.hbase.CategoryBasedTimeout;
30 import org.apache.hadoop.hbase.Cell;
31 import org.apache.hadoop.hbase.CellUtil;
32 import org.apache.hadoop.hbase.HBaseTestingUtility;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.client.Put;
35 import org.apache.hadoop.hbase.client.Result;
36 import org.apache.hadoop.hbase.client.ResultScanner;
37 import org.apache.hadoop.hbase.client.Scan;
38 import org.apache.hadoop.hbase.client.Table;
39 import org.apache.hadoop.hbase.mapreduce.SyncTable.SyncMapper.Counter;
40 import org.apache.hadoop.hbase.testclassification.LargeTests;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.mapreduce.Counters;
43 import org.junit.AfterClass;
44 import org.junit.Assert;
45 import org.junit.BeforeClass;
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.junit.experimental.categories.Category;
49 import org.junit.rules.TestRule;
50
51 import com.google.common.base.Throwables;
52
53
54
55
56 @Category(LargeTests.class)
57 public class TestSyncTable {
58 @Rule public final TestRule timeout = CategoryBasedTimeout.builder().
59 withTimeout(this.getClass()).withLookingForStuckThread(true).build();
60 private static final Log LOG = LogFactory.getLog(TestSyncTable.class);
61
62 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
63
64 @BeforeClass
65 public static void beforeClass() throws Exception {
66 TEST_UTIL.setJobWithoutMRCluster();
67 TEST_UTIL.startMiniCluster(3);
68 }
69
70 @AfterClass
71 public static void afterClass() throws Exception {
72 TEST_UTIL.cleanupDataTestDirOnTestFS();
73 TEST_UTIL.shutdownMiniCluster();
74 }
75
76 private static byte[][] generateSplits(int numRows, int numRegions) {
77 byte[][] splitRows = new byte[numRegions-1][];
78 for (int i = 1; i < numRegions; i++) {
79 splitRows[i-1] = Bytes.toBytes(numRows * i / numRegions);
80 }
81 return splitRows;
82 }
83
84 @Test
85 public void testSyncTable() throws Exception {
86 final TableName sourceTableName = TableName.valueOf("testSourceTable");
87 final TableName targetTableName = TableName.valueOf("testTargetTable");
88 Path testDir = TEST_UTIL.getDataTestDirOnTestFS("testSyncTable");
89
90 writeTestData(sourceTableName, targetTableName);
91 hashSourceTable(sourceTableName, testDir);
92 Counters syncCounters = syncTables(sourceTableName, targetTableName, testDir);
93 assertEqualTables(90, sourceTableName, targetTableName, false);
94
95 assertEquals(60, syncCounters.findCounter(Counter.ROWSWITHDIFFS).getValue());
96 assertEquals(10, syncCounters.findCounter(Counter.SOURCEMISSINGROWS).getValue());
97 assertEquals(10, syncCounters.findCounter(Counter.TARGETMISSINGROWS).getValue());
98 assertEquals(50, syncCounters.findCounter(Counter.SOURCEMISSINGCELLS).getValue());
99 assertEquals(50, syncCounters.findCounter(Counter.TARGETMISSINGCELLS).getValue());
100 assertEquals(20, syncCounters.findCounter(Counter.DIFFERENTCELLVALUES).getValue());
101
102 TEST_UTIL.deleteTable(sourceTableName);
103 TEST_UTIL.deleteTable(targetTableName);
104 }
105
106 @Test
107 public void testSyncTableDoDeletesFalse() throws Exception {
108 final TableName sourceTableName = TableName.valueOf("testSyncTableDoDeletesFalse_source");
109 final TableName targetTableName = TableName.valueOf("testSyncTableDoDeletesFalse_target");
110 Path testDir = TEST_UTIL.getDataTestDirOnTestFS("testSyncTableDoDeletesFalse");
111
112 writeTestData(sourceTableName, targetTableName);
113 hashSourceTable(sourceTableName, testDir);
114 Counters syncCounters = syncTables(sourceTableName, targetTableName,
115 testDir, "--doDeletes=false");
116 assertTargetDoDeletesFalse(100, sourceTableName, targetTableName);
117
118 assertEquals(60, syncCounters.findCounter(Counter.ROWSWITHDIFFS).getValue());
119 assertEquals(10, syncCounters.findCounter(Counter.SOURCEMISSINGROWS).getValue());
120 assertEquals(10, syncCounters.findCounter(Counter.TARGETMISSINGROWS).getValue());
121 assertEquals(50, syncCounters.findCounter(Counter.SOURCEMISSINGCELLS).getValue());
122 assertEquals(50, syncCounters.findCounter(Counter.TARGETMISSINGCELLS).getValue());
123 assertEquals(20, syncCounters.findCounter(Counter.DIFFERENTCELLVALUES).getValue());
124
125 TEST_UTIL.deleteTable(sourceTableName);
126 TEST_UTIL.deleteTable(targetTableName);
127 }
128
129 @Test
130 public void testSyncTableDoPutsFalse() throws Exception {
131 final TableName sourceTableName = TableName.valueOf("testSyncTableDoPutsFalse_source");
132 final TableName targetTableName = TableName.valueOf("testSyncTableDoPutsFalse_target");
133 Path testDir = TEST_UTIL.getDataTestDirOnTestFS("testSyncTableDoPutsFalse");
134
135 writeTestData(sourceTableName, targetTableName);
136 hashSourceTable(sourceTableName, testDir);
137 Counters syncCounters = syncTables(sourceTableName, targetTableName,
138 testDir, "--doPuts=false");
139 assertTargetDoPutsFalse(70, sourceTableName, targetTableName);
140
141 assertEquals(60, syncCounters.findCounter(Counter.ROWSWITHDIFFS).getValue());
142 assertEquals(10, syncCounters.findCounter(Counter.SOURCEMISSINGROWS).getValue());
143 assertEquals(10, syncCounters.findCounter(Counter.TARGETMISSINGROWS).getValue());
144 assertEquals(50, syncCounters.findCounter(Counter.SOURCEMISSINGCELLS).getValue());
145 assertEquals(50, syncCounters.findCounter(Counter.TARGETMISSINGCELLS).getValue());
146 assertEquals(20, syncCounters.findCounter(Counter.DIFFERENTCELLVALUES).getValue());
147
148 TEST_UTIL.deleteTable(sourceTableName);
149 TEST_UTIL.deleteTable(targetTableName);
150 }
151
152 @Test
153 public void testSyncTableIgnoreTimestampsTrue() throws Exception {
154 final TableName sourceTableName = TableName.valueOf("testSyncTableIgnoreTimestampsTrue_source");
155 final TableName targetTableName = TableName.valueOf("testSyncTableIgnoreTimestampsTrue_target");
156 Path testDir = TEST_UTIL.getDataTestDirOnTestFS("testSyncTableIgnoreTimestampsTrue");
157 long current = System.currentTimeMillis();
158 writeTestData(sourceTableName, targetTableName, current - 1000, current);
159 hashSourceTable(sourceTableName, testDir, "--ignoreTimestamps=true");
160 Counters syncCounters = syncTables(sourceTableName, targetTableName,
161 testDir, "--ignoreTimestamps=true");
162 assertEqualTables(90, sourceTableName, targetTableName, true);
163
164 assertEquals(50, syncCounters.findCounter(Counter.ROWSWITHDIFFS).getValue());
165 assertEquals(10, syncCounters.findCounter(Counter.SOURCEMISSINGROWS).getValue());
166 assertEquals(10, syncCounters.findCounter(Counter.TARGETMISSINGROWS).getValue());
167 assertEquals(30, syncCounters.findCounter(Counter.SOURCEMISSINGCELLS).getValue());
168 assertEquals(30, syncCounters.findCounter(Counter.TARGETMISSINGCELLS).getValue());
169 assertEquals(20, syncCounters.findCounter(Counter.DIFFERENTCELLVALUES).getValue());
170
171 TEST_UTIL.deleteTable(sourceTableName);
172 TEST_UTIL.deleteTable(targetTableName);
173 }
174
175 private void assertEqualTables(int expectedRows, TableName sourceTableName,
176 TableName targetTableName, boolean ignoreTimestamps) throws Exception {
177 Table sourceTable = TEST_UTIL.getConnection().getTable(sourceTableName);
178 Table targetTable = TEST_UTIL.getConnection().getTable(targetTableName);
179
180 ResultScanner sourceScanner = sourceTable.getScanner(new Scan());
181 ResultScanner targetScanner = targetTable.getScanner(new Scan());
182
183 for (int i = 0; i < expectedRows; i++) {
184 Result sourceRow = sourceScanner.next();
185 Result targetRow = targetScanner.next();
186
187 LOG.debug("SOURCE row: " + (sourceRow == null ? "null" : Bytes.toInt(sourceRow.getRow()))
188 + " cells:" + sourceRow);
189 LOG.debug("TARGET row: " + (targetRow == null ? "null" : Bytes.toInt(targetRow.getRow()))
190 + " cells:" + targetRow);
191
192 if (sourceRow == null) {
193 Assert.fail("Expected " + expectedRows
194 + " source rows but only found " + i);
195 }
196 if (targetRow == null) {
197 Assert.fail("Expected " + expectedRows
198 + " target rows but only found " + i);
199 }
200 Cell[] sourceCells = sourceRow.rawCells();
201 Cell[] targetCells = targetRow.rawCells();
202 if (sourceCells.length != targetCells.length) {
203 LOG.debug("Source cells: " + Arrays.toString(sourceCells));
204 LOG.debug("Target cells: " + Arrays.toString(targetCells));
205 Assert.fail("Row " + Bytes.toInt(sourceRow.getRow())
206 + " has " + sourceCells.length
207 + " cells in source table but " + targetCells.length
208 + " cells in target table");
209 }
210 for (int j = 0; j < sourceCells.length; j++) {
211 Cell sourceCell = sourceCells[j];
212 Cell targetCell = targetCells[j];
213 try {
214 if (!CellUtil.matchingRow(sourceCell, targetCell)) {
215 Assert.fail("Rows don't match");
216 }
217 if (!CellUtil.matchingFamily(sourceCell, targetCell)) {
218 Assert.fail("Families don't match");
219 }
220 if (!CellUtil.matchingQualifier(sourceCell, targetCell)) {
221 Assert.fail("Qualifiers don't match");
222 }
223 if (!ignoreTimestamps && !CellUtil.matchingTimestamp(sourceCell, targetCell)) {
224 Assert.fail("Timestamps don't match");
225 }
226 if (!CellUtil.matchingValue(sourceCell, targetCell)) {
227 Assert.fail("Values don't match");
228 }
229 } catch (Throwable t) {
230 LOG.debug("Source cell: " + sourceCell + " target cell: " + targetCell);
231 Throwables.propagate(t);
232 }
233 }
234 }
235 Result sourceRow = sourceScanner.next();
236 if (sourceRow != null) {
237 Assert.fail("Source table has more than " + expectedRows
238 + " rows. Next row: " + Bytes.toInt(sourceRow.getRow()));
239 }
240 Result targetRow = targetScanner.next();
241 if (targetRow != null) {
242 Assert.fail("Target table has more than " + expectedRows
243 + " rows. Next row: " + Bytes.toInt(targetRow.getRow()));
244 }
245 sourceScanner.close();
246 targetScanner.close();
247 sourceTable.close();
248 targetTable.close();
249 }
250
251 private void assertTargetDoDeletesFalse(int expectedRows, TableName
252 sourceTableName,
253 TableName targetTableName)
254 throws Exception {
255 Table sourceTable = TEST_UTIL.getConnection().getTable(sourceTableName);
256 Table targetTable = TEST_UTIL.getConnection().getTable(targetTableName);
257
258 ResultScanner sourceScanner = sourceTable.getScanner(new Scan());
259 ResultScanner targetScanner = targetTable.getScanner(new Scan());
260 Result targetRow = targetScanner.next();
261 Result sourceRow = sourceScanner.next();
262 int rowsCount = 0;
263 while (targetRow!=null) {
264 rowsCount++;
265
266
267 if (Bytes.toInt(sourceRow.getRow()) != Bytes.toInt(targetRow.getRow())) {
268 targetRow = targetScanner.next();
269 continue;
270 }
271
272 LOG.debug("SOURCE row: " + (sourceRow == null ? "null"
273 : Bytes.toInt(sourceRow.getRow()))
274 + " cells:" + sourceRow);
275 LOG.debug("TARGET row: " + (targetRow == null ? "null"
276 : Bytes.toInt(targetRow.getRow()))
277 + " cells:" + targetRow);
278
279 Cell[] sourceCells = sourceRow.rawCells();
280 Cell[] targetCells = targetRow.rawCells();
281 int targetRowKey = Bytes.toInt(targetRow.getRow());
282 if (targetRowKey >= 70 && targetRowKey < 80) {
283 if (sourceCells.length == targetCells.length) {
284 LOG.debug("Source cells: " + Arrays.toString(sourceCells));
285 LOG.debug("Target cells: " + Arrays.toString(targetCells));
286 Assert.fail("Row " + targetRowKey + " should have more cells in "
287 + "target than in source");
288 }
289
290 } else {
291 if (sourceCells.length != targetCells.length) {
292 LOG.debug("Source cells: " + Arrays.toString(sourceCells));
293 LOG.debug("Target cells: " + Arrays.toString(targetCells));
294 Assert.fail("Row " + Bytes.toInt(sourceRow.getRow())
295 + " has " + sourceCells.length
296 + " cells in source table but " + targetCells.length
297 + " cells in target table");
298 }
299 }
300 for (int j = 0; j < sourceCells.length; j++) {
301 Cell sourceCell = sourceCells[j];
302 Cell targetCell = targetCells[j];
303 try {
304 if (!CellUtil.matchingRow(sourceCell, targetCell)) {
305 Assert.fail("Rows don't match");
306 }
307 if (!CellUtil.matchingFamily(sourceCell, targetCell)) {
308 Assert.fail("Families don't match");
309 }
310 if (!CellUtil.matchingQualifier(sourceCell, targetCell)) {
311 Assert.fail("Qualifiers don't match");
312 }
313 if(targetRowKey < 80 && targetRowKey >= 90){
314 if (!CellUtil.matchingTimestamp(sourceCell, targetCell)) {
315 Assert.fail("Timestamps don't match");
316 }
317 }
318 if (!CellUtil.matchingValue(sourceCell, targetCell)) {
319 Assert.fail("Values don't match");
320 }
321 } catch (Throwable t) {
322 LOG.debug("Source cell: " + sourceCell + " target cell: "
323 + targetCell);
324 Throwables.propagate(t);
325 }
326 }
327 targetRow = targetScanner.next();
328 sourceRow = sourceScanner.next();
329 }
330 assertEquals("Target expected rows does not match.",expectedRows,
331 rowsCount);
332 sourceScanner.close();
333 targetScanner.close();
334 sourceTable.close();
335 targetTable.close();
336 }
337
338 private void assertTargetDoPutsFalse(int expectedRows, TableName
339 sourceTableName,
340 TableName targetTableName)
341 throws Exception {
342 Table sourceTable = TEST_UTIL.getConnection().getTable(sourceTableName);
343 Table targetTable = TEST_UTIL.getConnection().getTable(targetTableName);
344
345 ResultScanner sourceScanner = sourceTable.getScanner(new Scan());
346 ResultScanner targetScanner = targetTable.getScanner(new Scan());
347 Result targetRow = targetScanner.next();
348 Result sourceRow = sourceScanner.next();
349 int rowsCount = 0;
350
351 while (targetRow!=null) {
352
353
354 if (Bytes.toInt(sourceRow.getRow()) != Bytes.toInt(targetRow.getRow())) {
355 sourceRow = sourceScanner.next();
356 continue;
357 }
358
359 LOG.debug("SOURCE row: " + (sourceRow == null ?
360 "null" :
361 Bytes.toInt(sourceRow.getRow()))
362 + " cells:" + sourceRow);
363 LOG.debug("TARGET row: " + (targetRow == null ?
364 "null" :
365 Bytes.toInt(targetRow.getRow()))
366 + " cells:" + targetRow);
367
368 LOG.debug("rowsCount: " + rowsCount);
369
370 Cell[] sourceCells = sourceRow.rawCells();
371 Cell[] targetCells = targetRow.rawCells();
372 int targetRowKey = Bytes.toInt(targetRow.getRow());
373 if (targetRowKey >= 40 && targetRowKey < 60) {
374 LOG.debug("Source cells: " + Arrays.toString(sourceCells));
375 LOG.debug("Target cells: " + Arrays.toString(targetCells));
376 Assert.fail("There shouldn't exist any rows between 40 and 60, since "
377 + "Puts are disabled and Deletes are enabled.");
378 } else if (targetRowKey >= 60 && targetRowKey < 70) {
379 if (sourceCells.length == targetCells.length) {
380 LOG.debug("Source cells: " + Arrays.toString(sourceCells));
381 LOG.debug("Target cells: " + Arrays.toString(targetCells));
382 Assert.fail("Row " + Bytes.toInt(sourceRow.getRow())
383 + " shouldn't have same number of cells.");
384 }
385 } else if (targetRowKey >= 80 && targetRowKey < 90) {
386 LOG.debug("Source cells: " + Arrays.toString(sourceCells));
387 LOG.debug("Target cells: " + Arrays.toString(targetCells));
388 Assert.fail("There should be no rows between 80 and 90 on target, as "
389 + "these had different timestamps and should had been deleted.");
390 } else if (targetRowKey >= 90 && targetRowKey < 100) {
391 for (int j = 0; j < sourceCells.length; j++) {
392 Cell sourceCell = sourceCells[j];
393 Cell targetCell = targetCells[j];
394 if (CellUtil.matchingValue(sourceCell, targetCell)) {
395 Assert.fail("Cells values should not match for rows between "
396 + "90 and 100. Target row id: " + (Bytes.toInt(targetRow
397 .getRow())));
398 }
399 }
400 } else {
401 for (int j = 0; j < sourceCells.length; j++) {
402 Cell sourceCell = sourceCells[j];
403 Cell targetCell = targetCells[j];
404 try {
405 if (!CellUtil.matchingRow(sourceCell, targetCell)) {
406 Assert.fail("Rows don't match");
407 }
408 if (!CellUtil.matchingFamily(sourceCell, targetCell)) {
409 Assert.fail("Families don't match");
410 }
411 if (!CellUtil.matchingQualifier(sourceCell, targetCell)) {
412 Assert.fail("Qualifiers don't match");
413 }
414 if (!CellUtil.matchingTimestamp(sourceCell, targetCell)) {
415 Assert.fail("Timestamps don't match");
416 }
417 if (!CellUtil.matchingValue(sourceCell, targetCell)) {
418 Assert.fail("Values don't match");
419 }
420 } catch (Throwable t) {
421 LOG.debug(
422 "Source cell: " + sourceCell + " target cell: " + targetCell);
423 Throwables.propagate(t);
424 }
425 }
426 }
427 rowsCount++;
428 targetRow = targetScanner.next();
429 sourceRow = sourceScanner.next();
430 }
431 assertEquals("Target expected rows does not match.",expectedRows,
432 rowsCount);
433 sourceScanner.close();
434 targetScanner.close();
435 sourceTable.close();
436 targetTable.close();
437 }
438
439 private Counters syncTables(TableName sourceTableName, TableName targetTableName,
440 Path testDir, String... options) throws Exception {
441 SyncTable syncTable = new SyncTable(TEST_UTIL.getConfiguration());
442 String[] args = Arrays.copyOf(options, options.length+3);
443 args[options.length] = testDir.toString();
444 args[options.length+1] = sourceTableName.getNameAsString();
445 args[options.length+2] = targetTableName.getNameAsString();
446 int code = syncTable.run(args);
447 assertEquals("sync table job failed", 0, code);
448
449 LOG.info("Sync tables completed");
450 return syncTable.counters;
451 }
452
453 private void hashSourceTable(TableName sourceTableName, Path testDir, String... options)
454 throws Exception {
455 int numHashFiles = 3;
456 long batchSize = 100;
457 int scanBatch = 1;
458 HashTable hashTable = new HashTable(TEST_UTIL.getConfiguration());
459 String[] args = Arrays.copyOf(options, options.length + 5);
460 args[options.length] = "--batchsize=" + batchSize;
461 args[options.length + 1] = "--numhashfiles=" + numHashFiles;
462 args[options.length + 2] = "--scanbatch=" + scanBatch;
463 args[options.length + 3] = sourceTableName.getNameAsString();
464 args[options.length + 4] = testDir.toString();
465 int code = hashTable.run(args);
466 assertEquals("hash table job failed", 0, code);
467
468 FileSystem fs = TEST_UTIL.getTestFileSystem();
469
470 HashTable.TableHash tableHash = HashTable.TableHash.read(fs.getConf(), testDir);
471 assertEquals(sourceTableName.getNameAsString(), tableHash.tableName);
472 assertEquals(batchSize, tableHash.batchSize);
473 assertEquals(numHashFiles, tableHash.numHashFiles);
474 assertEquals(numHashFiles - 1, tableHash.partitions.size());
475
476 LOG.info("Hash table completed");
477 }
478
479 private void writeTestData(TableName sourceTableName, TableName targetTableName,
480 long... timestamps) throws Exception {
481 final byte[] family = Bytes.toBytes("family");
482 final byte[] column1 = Bytes.toBytes("c1");
483 final byte[] column2 = Bytes.toBytes("c2");
484 final byte[] value1 = Bytes.toBytes("val1");
485 final byte[] value2 = Bytes.toBytes("val2");
486 final byte[] value3 = Bytes.toBytes("val3");
487
488 int numRows = 100;
489 int sourceRegions = 10;
490 int targetRegions = 6;
491 if (ArrayUtils.isEmpty(timestamps)) {
492 long current = System.currentTimeMillis();
493 timestamps = new long[]{current,current};
494 }
495 Table sourceTable = TEST_UTIL.createTable(sourceTableName,
496 family, generateSplits(numRows, sourceRegions));
497
498 Table targetTable = TEST_UTIL.createTable(targetTableName,
499 family, generateSplits(numRows, targetRegions));
500
501 int rowIndex = 0;
502
503 for (; rowIndex < 40; rowIndex++) {
504 Put sourcePut = new Put(Bytes.toBytes(rowIndex));
505 sourcePut.addColumn(family, column1, timestamps[0], value1);
506 sourcePut.addColumn(family, column2, timestamps[0], value2);
507 sourceTable.put(sourcePut);
508
509 Put targetPut = new Put(Bytes.toBytes(rowIndex));
510 targetPut.addColumn(family, column1, timestamps[1], value1);
511 targetPut.addColumn(family, column2, timestamps[1], value2);
512 targetTable.put(targetPut);
513 }
514
515
516
517
518 for (; rowIndex < 50; rowIndex++) {
519 Put put = new Put(Bytes.toBytes(rowIndex));
520 put.addColumn(family, column1, timestamps[0], value1);
521 put.addColumn(family, column2, timestamps[0], value2);
522 sourceTable.put(put);
523 }
524
525
526
527
528 for (; rowIndex < 60; rowIndex++) {
529 Put put = new Put(Bytes.toBytes(rowIndex));
530 put.addColumn(family, column1, timestamps[1], value1);
531 put.addColumn(family, column2, timestamps[1], value2);
532 targetTable.put(put);
533 }
534
535
536
537 for (; rowIndex < 70; rowIndex++) {
538 Put sourcePut = new Put(Bytes.toBytes(rowIndex));
539 sourcePut.addColumn(family, column1, timestamps[0], value1);
540 sourcePut.addColumn(family, column2, timestamps[0], value2);
541 sourceTable.put(sourcePut);
542
543 Put targetPut = new Put(Bytes.toBytes(rowIndex));
544 targetPut.addColumn(family, column1, timestamps[1], value1);
545 targetTable.put(targetPut);
546 }
547
548
549
550 for (; rowIndex < 80; rowIndex++) {
551 Put sourcePut = new Put(Bytes.toBytes(rowIndex));
552 sourcePut.addColumn(family, column1, timestamps[0], value1);
553 sourceTable.put(sourcePut);
554
555 Put targetPut = new Put(Bytes.toBytes(rowIndex));
556 targetPut.addColumn(family, column1, timestamps[1], value1);
557 targetPut.addColumn(family, column2, timestamps[1], value2);
558 targetTable.put(targetPut);
559 }
560
561
562
563
564 for (; rowIndex < 90; rowIndex++) {
565 Put sourcePut = new Put(Bytes.toBytes(rowIndex));
566 sourcePut.addColumn(family, column1, timestamps[0], column1);
567 sourcePut.addColumn(family, column2, timestamps[0], value2);
568 sourceTable.put(sourcePut);
569
570 Put targetPut = new Put(Bytes.toBytes(rowIndex));
571 targetPut.addColumn(family, column1, timestamps[1]+1, column1);
572 targetPut.addColumn(family, column2, timestamps[1]-1, value2);
573 targetTable.put(targetPut);
574 }
575
576
577
578 for (; rowIndex < numRows; rowIndex++) {
579 Put sourcePut = new Put(Bytes.toBytes(rowIndex));
580 sourcePut.addColumn(family, column1, timestamps[0], value1);
581 sourcePut.addColumn(family, column2, timestamps[0], value2);
582 sourceTable.put(sourcePut);
583
584 Put targetPut = new Put(Bytes.toBytes(rowIndex));
585 targetPut.addColumn(family, column1, timestamps[1], value3);
586 targetPut.addColumn(family, column2, timestamps[1], value3);
587 targetTable.put(targetPut);
588 }
589
590 sourceTable.close();
591 targetTable.close();
592 }
593
594
595 }