private boolean isExpired(final KeySliceQuery query) { Long until = expiredKeys.get(query.getKey()); if (until==null) return false; if (isBeyondExpirationTime(until)) { expiredKeys.remove(query.getKey(),until); return false; } //We suffer a cache miss, hence decrease the count down penaltyCountdown.countDown(); return true; }
@Override public void run() { while (true) { if (stop) return; try { penaltyCountdown.await(); } catch (InterruptedException e) { if (stop) return; else throw new RuntimeException("Cleanup thread got interrupted",e); } //Do clean up work by invalidating all entries for expired keys final Map<StaticBuffer,Long> expiredKeysCopy = new HashMap<>(expiredKeys.size()); for (Map.Entry<StaticBuffer,Long> expKey : expiredKeys.entrySet()) { if (isBeyondExpirationTime(expKey.getValue())) expiredKeys.remove(expKey.getKey(), expKey.getValue()); else if (getAge(expKey.getValue())>= invalidationGracePeriodMS) expiredKeysCopy.put(expKey.getKey(),expKey.getValue()); } for (KeySliceQuery ksq : cache.asMap().keySet()) { if (expiredKeysCopy.containsKey(ksq.getKey())) cache.invalidate(ksq); } penaltyCountdown = new CountDownLatch(PENALTY_THRESHOLD); for (Map.Entry<StaticBuffer,Long> expKey : expiredKeysCopy.entrySet()) { expiredKeys.remove(expKey.getKey(),expKey.getValue()); } } }
@Override public EntryList getSlice(KeySliceQuery query, StoreTransaction txh) throws BackendException { ColumnValueStore cvs = kcv.get(query.getKey()); if (cvs == null) return EntryList.EMPTY_LIST; else return cvs.getSlice(query, txh); }
final KVQuery convertQuery(final KeySliceQuery query) { Predicate<StaticBuffer> filter = Predicates.alwaysTrue(); if (!hasFixedKeyLength()) { filter = keyAndColumn -> equalKey(keyAndColumn, query.getKey()); } return new KVQuery( concatenatePrefix(query.getKey(), query.getSliceStart()), concatenatePrefix(query.getKey(), query.getSliceEnd()), filter,query.getLimit()); }
@Override public EntryList getSlice(KeySliceQuery query, StoreTransaction txh) throws BackendException { Map<StaticBuffer, EntryList> result = getHelper(Arrays.asList(query.getKey()), getFilter(query)); return Iterables.getOnlyElement(result.values(), EntryList.EMPTY_LIST); }
@Override public EntryList getSlice(final KeySliceQuery query, final StoreTransaction txh) throws BackendException { log.debug("Entering getSliceKeySliceQuery table:{} query:{} txh:{}", getTableName(), encodeForLog(query), txh); final EntryList result = getKeysRangeQuery(query.getKey(), query, txh); log.debug("Exiting getSliceKeySliceQuery table:{} query:{} txh:{} returning:{}", getTableName(), encodeForLog(query), txh, result.size()); return result; }
protected String encodeForLog(final KeySliceQuery query) { return "keyslice[hk:" + encodeKeyForLog(query.getKey()) + " " + "rk:" + encodeKeyForLog(query.getSliceStart()) + " -> " + encodeKeyForLog(query.getSliceEnd()) + " limit:" + query.getLimit() + "]"; }
@Override public EntryList getSlice(final KeySliceQuery query, final StoreTransaction txh) throws BackendException { log.debug("Entering getSliceKeySliceQuery table:{} query:{} txh:{}", getTableName(), encodeForLog(query), txh); final GetItemRequest request = super.createGetItemRequest().withKey(new ItemBuilder().hashKey(query.getKey()).build()); final GetItemResult result = new ExponentialBackoff.GetItem(request, client.getDelegate()).runWithBackoff(); final List<Entry> filteredEntries = extractEntriesFromGetItemResult(result, query.getSliceStart(), query.getSliceEnd(), query.getLimit()); log.debug("Exiting getSliceKeySliceQuery table:{} query:{} txh:{} returning:{}", getTableName(), encodeForLog(query), txh, filteredEntries.size()); return StaticArrayEntryList.of(filteredEntries); }
@Override public EntryList getSlice(final KeySliceQuery query, final StoreTransaction txh) throws BackendException { final Future<EntryList> result = Future.fromJavaFuture( this.executorService, this.session.executeAsync(this.getSlice.bind() .setBytes(KEY_BINDING, query.getKey().asByteBuffer()) .setBytes(SLICE_START_BINDING, query.getSliceStart().asByteBuffer()) .setBytes(SLICE_END_BINDING, query.getSliceEnd().asByteBuffer()) .setInt(LIMIT_BINDING, query.getLimit()) .setConsistencyLevel(getTransaction(txh).getReadConsistencyLevel()))) .map(resultSet -> fromResultSet(resultSet, this.getter)); interruptibleWait(result); return result.getValue().get().getOrElseThrow(EXCEPTION_MAPPER); }