/** * Get position updating key cache and stats. * @see #getPosition(org.apache.cassandra.db.RowPosition, org.apache.cassandra.io.sstable.SSTableReader.Operator, boolean) */ public RowIndexEntry getPosition(RowPosition key, Operator op) { return getPosition(key, op, true); }
public SSTableSliceIterator(SSTableReader sstable, DecoratedKey key, ColumnSlice[] slices, boolean reversed) { this.key = key; RowIndexEntry indexEntry = sstable.getPosition(key, SSTableReader.Operator.EQ); this.reader = indexEntry == null ? null : createReader(sstable, indexEntry, null, slices, reversed); }
public List<String> getSSTablesForKey(String key) { DecoratedKey dk = partitioner.decorateKey(metadata.getKeyValidator().fromString(key)); try (OpOrder.Group op = readOrdering.start()) { List<String> files = new ArrayList<>(); for (SSTableReader sstr : select(viewFilter(dk)).sstables) { // check if the key actually exists in this sstable, without updating cache and stats if (sstr.getPosition(dk, SSTableReader.Operator.EQ, false) != null) files.add(sstr.getFilename()); } return files; } }
public SSTableReader cloneWithNewStart(DecoratedKey newStart, final Runnable runOnClose) { synchronized (tidy.global) { assert openReason != OpenReason.EARLY; // TODO: merge with caller's firstKeyBeyond() work,to save time if (newStart.compareTo(first) > 0) { final long dataStart = getPosition(newStart, Operator.EQ).position; final long indexStart = getIndexScanPosition(newStart); this.tidy.runOnClose = new DropPageCache(dfile, dataStart, ifile, indexStart, runOnClose); } return cloneAndReplace(newStart, OpenReason.MOVED_START); } }
/** * @return the largest timestamp before which it's okay to drop tombstones for the given partition; * i.e., after the maxPurgeableTimestamp there may exist newer data that still needs to be suppressed * in other sstables. This returns the minimum timestamp for any SSTable that contains this partition and is not * participating in this compaction, or LONG.MAX_VALUE if no such SSTable exists. */ public long maxPurgeableTimestamp(DecoratedKey key) { if (NEVER_PURGE_TOMBSTONES) return Long.MIN_VALUE; List<SSTableReader> filteredSSTables = overlappingTree.search(key); long min = Long.MAX_VALUE; for (SSTableReader sstable : filteredSSTables) { // if we don't have bloom filter(bf_fp_chance=1.0 or filter file is missing), // we check index file instead. if (sstable.getBloomFilter() instanceof AlwaysPresentFilter && sstable.getPosition(key, SSTableReader.Operator.EQ, false) != null) min = Math.min(min, sstable.getMinTimestamp()); else if (sstable.getBloomFilter().isPresent(key.getKey())) min = Math.min(min, sstable.getMinTimestamp()); } return min; }
private void maybeReopenEarly(DecoratedKey key) { if (writer.getFilePointer() - currentlyOpenedEarlyAt > preemptiveOpenInterval) { if (isOffline) { for (SSTableReader reader : rewriting) { RowIndexEntry index = reader.getPosition(key, SSTableReader.Operator.GE); CLibrary.trySkipCache(fileDescriptors.get(reader.descriptor), 0, index == null ? 0 : index.position); } } else { SSTableReader reader = writer.openEarly(maxAge); if (reader != null) { replaceEarlyOpenedFile(currentlyOpenedEarly, reader); currentlyOpenedEarly = reader; currentlyOpenedEarlyAt = writer.getFilePointer(); moveStarts(reader, reader.last, false); } } } }
/** * Determine the minimal set of sections that can be extracted from this SSTable to cover the given ranges. * @return A sorted list of (offset,end) pairs that cover the given ranges in the datafile for this SSTable. */ public List<Pair<Long,Long>> getPositionsForRanges(Collection<Range<Token>> ranges) { // use the index to determine a minimal section for each range List<Pair<Long,Long>> positions = new ArrayList<>(); for (Range<Token> range : Range.normalize(ranges)) { assert !range.isWrapAround() || range.right.isMinimum(); // truncate the range so it at most covers the sstable AbstractBounds<RowPosition> bounds = range.toRowBounds(); RowPosition leftBound = bounds.left.compareTo(first) > 0 ? bounds.left : first.getToken().minKeyBound(); RowPosition rightBound = bounds.right.isMinimum() ? last.getToken().maxKeyBound() : bounds.right; if (leftBound.compareTo(last) > 0 || rightBound.compareTo(first) < 0) continue; long left = getPosition(leftBound, Operator.GT).position; long right = (rightBound.compareTo(last) > 0) ? uncompressedLength() : getPosition(rightBound, Operator.GT).position; if (left == right) // empty range continue; assert left < right : String.format("Range=%s openReason=%s first=%s last=%s left=%d right=%d", range, openReason, first, last, left, right); positions.add(Pair.create(left, right)); } return positions; }
public SSTableNamesIterator(SSTableReader sstable, DecoratedKey key, SortedSet<CellName> columns) { assert columns != null; this.sstable = sstable; this.columns = columns; this.key = key; RowIndexEntry indexEntry = sstable.getPosition(key, SSTableReader.Operator.EQ); if (indexEntry == null) return; try { read(sstable, null, indexEntry); } catch (IOException e) { sstable.markSuspect(); throw new CorruptSSTableException(e, sstable.getFilename()); } finally { if (fileToClose != null) FileUtils.closeQuietly(fileToClose); } }
RowIndexEntry entry = sstable.getPosition(decoratedKey, SSTableReader.Operator.EQ); if (entry == null) continue;
private RowIndexEntry getPosition(RowPosition key, Operator op, boolean updateCacheAndStats, boolean permitMatchPastLast) { // first, check bloom filter if (op == Operator.EQ) { assert key instanceof DecoratedKey; // EQ only make sense if the key is a valid row key if (!bf.isPresent(((DecoratedKey)key).getKey())) { Tracing.trace("Bloom filter allows skipping sstable {}", descriptor.generation); return null; } } // next, the key cache (only make sense for valid row key) if ((op == Operator.EQ || op == Operator.GE) && (key instanceof DecoratedKey)) { DecoratedKey decoratedKey = (DecoratedKey)key; KeyCacheKey cacheKey = new KeyCacheKey(metadata.ksAndCFName, descriptor, decoratedKey.getKey()); RowIndexEntry cachedPosition = getCachedPosition(cacheKey, updateCacheAndStats); if (cachedPosition != null) { Tracing.trace("Key cache hit for sstable {}", descriptor.generation); return cachedPosition; } } // check the smallest and greatest keys in the sstable to see if it can't be present boolean skip = false; if (key.compareTo(first) < 0) {