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 KeySliceQuery updateLimit(int newLimit) { return new KeySliceQuery(key,this).setLimit(newLimit); }
EntryList getSlice(KeySliceQuery query, StoreTransaction txh) { Lock lock = getLock(txh); lock.lock(); try { Data datacp = data; int start = datacp.getIndex(query.getSliceStart()); if (start < 0) start = (-start - 1); int end = datacp.getIndex(query.getSliceEnd()); if (end < 0) end = (-end - 1); if (start < end) { MemoryEntryList result = new MemoryEntryList(end - start); for (int i = start; i < end; i++) { if (query.hasLimit() && result.size() >= query.getLimit()) break; result.add(datacp.get(i)); } return result; } else { return EntryList.EMPTY_LIST; } } finally { lock.unlock(); } }
@Override public String toString() { return String.format("KeySliceQuery(key: %s, start: %s, end: %s, limit:%d)", key, getSliceStart(), getSliceEnd(), getLimit()); } }
@Override public Map<StaticBuffer,EntryList> getSlice(List<StaticBuffer> keys, SliceQuery query, StoreTransaction txh) throws BackendException { Map<StaticBuffer,EntryList> result = Maps.newHashMap(); for (StaticBuffer key : keys) result.put(key,getSlice(new KeySliceQuery(key,query),txh)); return result; }
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 boolean hasNext() { ensureOpen(); if (null != nextRow) return true; while (rows.hasNext()) { nextRow = rows.next(); List<Entry> entries = nextRow.getValue().getSlice(new KeySliceQuery(nextRow.getKey(), columnSlice), transaction); if (null != entries && 0 < entries.size()) break; } return null != nextRow; }
@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()); } } }
protected String encodeForLog(final KeySliceQuery query) { return "keyslice[hk:" + encodeKeyForLog(query.getKey()) + " " + "rk:" + encodeKeyForLog(query.getSliceStart()) + " -> " + encodeKeyForLog(query.getSliceEnd()) + " limit:" + query.getLimit() + "]"; }
public static boolean containsKey(KeyColumnValueStore store, StaticBuffer key, int maxColumnLength, StoreTransaction txh) throws BackendException { final StaticBuffer end; if (maxColumnLength>32) { end = BufferUtil.oneBuffer(maxColumnLength); } else { end = END; } return !store.getSlice(new KeySliceQuery(key, START, end).setLimit(1),txh).isEmpty(); }
@Override public Map<StaticBuffer,EntryList> getSlice(List<StaticBuffer> keys, SliceQuery query, StoreTransaction txh) throws BackendException { final List<KVQuery> queries = new ArrayList<>(keys.size()); for (StaticBuffer key : keys) { queries.add(convertQuery(new KeySliceQuery(key, query))); } final Map<KVQuery,RecordIterator<KeyValueEntry>> results = store.getSlices(queries,txh); final Map<StaticBuffer,EntryList> convertedResults = new HashMap<>(keys.size()); assert queries.size()==keys.size(); for (int i = 0; i < queries.size(); i++) { convertedResults.put(keys.get(i),convert(results.get(queries.get(i)))); } return convertedResults; }
@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); }
@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); }
private long getCurrentID(final StaticBuffer partitionKey) throws BackendException { final List<Entry> blocks = BackendOperation.execute( (BackendOperation.Transactional<List<Entry>>) txh -> idStore.getSlice(new KeySliceQuery(partitionKey, LOWER_SLICE, UPPER_SLICE).setLimit(5), txh),this,times); if (blocks == null) throw new TemporaryBackendException("Could not read from storage"); long latest = BASE_ID; for (Entry e : blocks) { long counterVal = getBlockValue(e); if (latest < counterVal) { latest = counterVal; } } return latest; }
public EntryList edgeQuery(long vid, SliceQuery query, BackendTransaction tx) { Preconditions.checkArgument(vid > 0); return tx.edgeStoreQuery(new KeySliceQuery(idManager.getKey(vid), query)); }
@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 { 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); }
/** * Retrieves the value for the specified column and key under the given transaction * from the store if such exists, otherwise returns NULL * * @param store Store * @param key Key * @param column Column * @param txh Transaction * @return Value for key and column or NULL if such does not exist */ public static StaticBuffer get(KeyColumnValueStore store, StaticBuffer key, StaticBuffer column, StoreTransaction txh) throws BackendException { KeySliceQuery query = new KeySliceQuery(key, column, BufferUtil.nextBiggerBuffer(column)).setLimit(2); List<Entry> result = store.getSlice(query, txh); if (result.size() > 1) log.warn("GET query returned more than 1 result: store {} | key {} | column {}", store.getName(), key, column); if (result.isEmpty()) return null; else return result.get(0).getValueAs(StaticBuffer.STATIC_FACTORY); }
public MultiKeySliceQuery getQuery(final CompositeIndexType index, List<Object[]> values) { final List<KeySliceQuery> ksqs = new ArrayList<>(values.size()); for (final Object[] value : values) { ksqs.add(new KeySliceQuery(getIndexKey(index,value), BufferUtil.zeroBuffer(1), BufferUtil.oneBuffer(1))); } return new MultiKeySliceQuery(ksqs); }
@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; }