private KCVMutation convert(KCVEntryMutation mutation) { assert !mutation.isEmpty(); if (!mutation.hasDeletions()) return new KCVMutation(mutation.getAdditions(), KeyColumnValueStore.NO_DELETIONS); else return new KCVMutation(mutation.getAdditions(), Lists.newArrayList(Iterables.transform(mutation.getDeletions(), KCVEntryMutation.ENTRY2COLUMN_FCT))); }
@Test public void testMutateManyWithoutLockUsesInconsistentTx() throws BackendException { final ImmutableList<Entry> adds = ImmutableList.of(StaticArrayEntry.of(DATA_COL, DATA_VAL)); final ImmutableList<StaticBuffer> deletions = ImmutableList.of(); Map<String, Map<StaticBuffer, KCVMutation>> mutations = ImmutableMap.of(STORE_NAME, ImmutableMap.of(DATA_KEY, new KCVMutation(adds, deletions))); // Run mutateMany backingManager.mutateMany(mutations, inconsistentTx); // consistency level is unconstrained w/o locks ctrl.replay(); // Run mutateMany expectManager.mutateMany(mutations, expectTx); } }
@Test public void testMutateManyWithLockUsesConsistentTx() throws BackendException { final ImmutableList<Entry> adds = ImmutableList.of(StaticArrayEntry.of(DATA_COL, DATA_VAL)); final ImmutableList<StaticBuffer> deletions = ImmutableList.of(); Map<String, Map<StaticBuffer, KCVMutation>> mutations = ImmutableMap.of(STORE_NAME, ImmutableMap.of(DATA_KEY, new KCVMutation(adds, deletions))); final KeyColumn kc = new KeyColumn(LOCK_KEY, LOCK_COL); // Acquire a lock backingLocker.writeLock(kc, consistentTx); // 2. Run mutateMany // 2.1. Check locks & expected values before mutating data backingLocker.checkLocks(consistentTx); StaticBuffer nextBuf = BufferUtil.nextBiggerBuffer(kc.getColumn()); KeySliceQuery expectedValueQuery = new KeySliceQuery(kc.getKey(), kc.getColumn(), nextBuf); expect(backingStore.getSlice(expectedValueQuery, consistentTx)) // expected value read must use strong consistency .andReturn(StaticArrayEntryList.of(StaticArrayEntry.of(LOCK_COL, LOCK_VAL))); // 2.2. Run mutateMany on backing manager to modify data backingManager.mutateMany(mutations, consistentTx); // writes by txs with locks must use strong consistency ctrl.replay(); // Lock acquisition expectStore.acquireLock(LOCK_KEY, LOCK_COL, LOCK_VAL, expectTx); // Mutate expectManager.mutateMany(mutations, expectTx); }
@Test public void mutateManyWritesSameKeyOnMultipleCFs() throws BackendException { final long arbitraryLong = 42; //must be greater than 0 final StaticBuffer key = KeyColumnValueStoreUtil.longToByteBuffer(arbitraryLong * arbitraryLong); final StaticBuffer val = KeyColumnValueStoreUtil.longToByteBuffer(arbitraryLong * arbitraryLong * arbitraryLong); final StaticBuffer col = KeyColumnValueStoreUtil.longToByteBuffer(arbitraryLong); final StaticBuffer nextCol = KeyColumnValueStoreUtil.longToByteBuffer(arbitraryLong + 1); final StoreTransaction directTx = manager.beginTransaction(getTxConfig()); KCVMutation km = new KCVMutation( Lists.newArrayList(StaticArrayEntry.of(col, val)), Lists.newArrayList()); Map<StaticBuffer, KCVMutation> keyColumnAndValue = ImmutableMap.of(key, km); Map<String, Map<StaticBuffer, KCVMutation>> mutations = ImmutableMap.of( storeName1, keyColumnAndValue, storeName2, keyColumnAndValue); manager.mutateMany(mutations, directTx); directTx.commit(); KeySliceQuery query = new KeySliceQuery(key, col, nextCol); List<Entry> expected = ImmutableList.of(StaticArrayEntry.of(col, val)); Assert.assertEquals(expected, store1.getSlice(query, tx)); Assert.assertEquals(expected, store2.getSlice(query, tx)); }
new KCVMutation(ImmutableList.of(StaticArrayEntry.of(col, val2)), ImmutableList.of())));
@Override public void mutate(final StaticBuffer key, final List<Entry> additions, final List<StaticBuffer> deletions, final StoreTransaction txh) throws BackendException { this.storeManager.mutateMany(Collections.singletonMap(this.tableName, Collections.singletonMap(key, new KCVMutation(additions, deletions))), txh); }
@Override public void mutate(StaticBuffer key, List<Entry> additions, List<StaticBuffer> deletions, StoreTransaction txh) throws BackendException { Map<StaticBuffer, KCVMutation> mutations = ImmutableMap.of(key, new KCVMutation(additions, deletions)); mutateMany(mutations, txh); }
@Override public void mutate(final StaticBuffer hashKey, final List<Entry> additions, final List<StaticBuffer> deletions, final StoreTransaction txh) throws BackendException { log.debug("Entering mutate table:{} keys:{} additions:{} deletions:{} txh:{}", getTableName(), encodeKeyForLog(hashKey), encodeForLog(additions), encodeForLog(deletions), txh); super.mutateOneKey(hashKey, new KCVMutation(additions, deletions), txh); log.debug("Exiting mutate table:{} keys:{} additions:{} deletions:{} txh:{} returning:void", getTableName(), encodeKeyForLog(hashKey), encodeForLog(additions), encodeForLog(deletions), txh); }
@Override public void mutate(final StaticBuffer key, final List<Entry> additions, final List<StaticBuffer> deletions, final StoreTransaction txh) throws BackendException { log.debug("Entering mutate table:{} keys:{} additions:{} deletions:{} txh:{}", getTableName(), encodeKeyForLog(key), encodeForLog(additions), encodeForLog(deletions), txh); // this method also filters out deletions that are also added super.mutateOneKey(key, new KCVMutation(additions, deletions), txh); log.debug("Exiting mutate table:{} keys:{} additions:{} deletions:{} txh:{} returning:void", getTableName(), encodeKeyForLog(key), encodeForLog(additions), encodeForLog(deletions), txh); }