@Test public void testRowCacheRange() { CompactionManager.instance.disableAutoCompaction(); Keyspace keyspace = Keyspace.open(KEYSPACE_CACHED); String cf = "CachedIntCF"; ColumnFamilyStore cachedStore = keyspace.getColumnFamilyStore(cf); long startRowCacheHits = cachedStore.metric.rowCacheHit.getCount(); long startRowCacheOutOfRange = cachedStore.metric.rowCacheHitOutOfRange.getCount(); // empty the row cache CacheService.instance.invalidateRowCache(); // set global row cache size to 1 MB CacheService.instance.setRowCacheCapacityInMB(1); ByteBuffer key = ByteBufferUtil.bytes("rowcachekey"); DecoratedKey dk = cachedStore.partitioner.decorateKey(key); RowCacheKey rck = new RowCacheKey(cachedStore.metadata.ksAndCFName, dk); Mutation mutation = new Mutation(KEYSPACE_CACHED, key); for (int i = 0; i < 200; i++) mutation.add( cf, Util.cellname(i), ByteBufferUtil.bytes("val" + i), System.currentTimeMillis()); mutation.applyUnsafe(); // populate row cache, we should not get a row cache hit; cachedStore.getColumnFamily( QueryFilter.getSliceFilter( dk, cf, Composites.EMPTY, Composites.EMPTY, false, 10, System.currentTimeMillis())); assertEquals(startRowCacheHits, cachedStore.metric.rowCacheHit.getCount()); // do another query, limit is 20, which is < 100 that we cache, we should get a hit and it // should be in range cachedStore.getColumnFamily( QueryFilter.getSliceFilter( dk, cf, Composites.EMPTY, Composites.EMPTY, false, 20, System.currentTimeMillis())); assertEquals(++startRowCacheHits, cachedStore.metric.rowCacheHit.getCount()); assertEquals(startRowCacheOutOfRange, cachedStore.metric.rowCacheHitOutOfRange.getCount()); // get a slice from 95 to 105, 95->99 are in cache, we should not get a hit and then row cache // is out of range cachedStore.getColumnFamily( QueryFilter.getSliceFilter( dk, cf, CellNames.simpleDense(ByteBufferUtil.bytes(95)), CellNames.simpleDense(ByteBufferUtil.bytes(105)), false, 10, System.currentTimeMillis())); assertEquals(startRowCacheHits, cachedStore.metric.rowCacheHit.getCount()); assertEquals(++startRowCacheOutOfRange, cachedStore.metric.rowCacheHitOutOfRange.getCount()); // get a slice with limit > 100, we should get a hit out of range. cachedStore.getColumnFamily( QueryFilter.getSliceFilter( dk, cf, Composites.EMPTY, Composites.EMPTY, false, 101, System.currentTimeMillis())); assertEquals(startRowCacheHits, cachedStore.metric.rowCacheHit.getCount()); assertEquals(++startRowCacheOutOfRange, cachedStore.metric.rowCacheHitOutOfRange.getCount()); CacheService.instance.invalidateRowCache(); // try to populate row cache with a limit > rows to cache, we should still populate row cache; cachedStore.getColumnFamily( QueryFilter.getSliceFilter( dk, cf, Composites.EMPTY, Composites.EMPTY, false, 105, System.currentTimeMillis())); assertEquals(startRowCacheHits, cachedStore.metric.rowCacheHit.getCount()); // validate the stuff in cache; ColumnFamily cachedCf = (ColumnFamily) CacheService.instance.rowCache.get(rck); assertEquals(cachedCf.getColumnCount(), 100); int i = 0; for (Cell c : cachedCf) { assertEquals(c.name(), Util.cellname(i++)); } }
@Test public void testRowCache() throws Exception { CompactionManager.instance.disableAutoCompaction(); Keyspace keyspace = Keyspace.open(KEYSPACE_CACHED); ColumnFamilyStore cachedStore = keyspace.getColumnFamilyStore(CF_CACHED); // empty the row cache CacheService.instance.invalidateRowCache(); // set global row cache size to 1 MB CacheService.instance.setRowCacheCapacityInMB(1); // inserting 100 rows into both column families SchemaLoader.insertData(KEYSPACE_CACHED, CF_CACHED, 0, 100); // now reading rows one by one and checking if row change grows for (int i = 0; i < 100; i++) { DecoratedKey key = Util.dk("key" + i); cachedStore.getColumnFamily( key, Composites.EMPTY, Composites.EMPTY, false, 1, System.currentTimeMillis()); assert CacheService.instance.rowCache.size() == i + 1; assert cachedStore.containsCachedRow(key); // current key should be stored in the cache // checking if cell is read correctly after cache ColumnFamily cf = cachedStore.getColumnFamily( key, Composites.EMPTY, Composites.EMPTY, false, 1, System.currentTimeMillis()); Collection<Cell> cells = cf.getSortedColumns(); Cell cell = cells.iterator().next(); assert cells.size() == 1; assert cell.name().toByteBuffer().equals(ByteBufferUtil.bytes("col" + i)); assert cell.value().equals(ByteBufferUtil.bytes("val" + i)); } // insert 10 more keys SchemaLoader.insertData(KEYSPACE_CACHED, CF_CACHED, 100, 10); for (int i = 100; i < 110; i++) { DecoratedKey key = Util.dk("key" + i); cachedStore.getColumnFamily( key, Composites.EMPTY, Composites.EMPTY, false, 1, System.currentTimeMillis()); assert cachedStore.containsCachedRow( key); // cache should be populated with the latest rows read (old ones should be popped) // checking if cell is read correctly after cache ColumnFamily cf = cachedStore.getColumnFamily( key, Composites.EMPTY, Composites.EMPTY, false, 1, System.currentTimeMillis()); Collection<Cell> cells = cf.getSortedColumns(); Cell cell = cells.iterator().next(); assert cells.size() == 1; assert cell.name().toByteBuffer().equals(ByteBufferUtil.bytes("col" + i)); assert cell.value().equals(ByteBufferUtil.bytes("val" + i)); } // clear 100 rows from the cache int keysLeft = 109; for (int i = 109; i >= 10; i--) { cachedStore.invalidateCachedRow(Util.dk("key" + i)); assert CacheService.instance.rowCache.size() == keysLeft; keysLeft--; } CacheService.instance.setRowCacheCapacityInMB(0); }
public static ColumnFamily getColumnFamily(Keyspace keyspace, DecoratedKey key, String cfName) { ColumnFamilyStore cfStore = keyspace.getColumnFamilyStore(cfName); assert cfStore != null : "Table " + cfName + " has not been defined"; return cfStore.getColumnFamily( QueryFilter.getIdentityFilter(key, cfName, System.currentTimeMillis())); }