private int discardLast(ColumnFamily cf, int toDiscard, ColumnFamily newCf) { boolean isReversed = isReversed(); DeletionInfo.InOrderTester tester = cf.deletionInfo().inOrderTester(isReversed); return isReversed ? discardHead(cf, toDiscard, newCf, cf.reverseIterator(), tester) : discardTail(cf, toDiscard, newCf, cf.iterator(), tester); }
public Iterator<RangeTombstone> getRangeTombstoneIterator(final ColumnFamily source) { final DeletionInfo delInfo = source.deletionInfo(); if (!delInfo.hasRanges() || slices.length == 0) return Iterators.emptyIterator(); return new AbstractIterator<RangeTombstone>() { private int sliceIdx = 0; private Iterator<RangeTombstone> sliceIter = currentRangeIter(); protected RangeTombstone computeNext() { while (true) { if (sliceIter.hasNext()) return sliceIter.next(); if (!nextSlice()) return endOfData(); sliceIter = currentRangeIter(); } } private Iterator<RangeTombstone> currentRangeIter() { ColumnSlice slice = slices[reversed ? (slices.length - 1 - sliceIdx) : sliceIdx]; return reversed ? delInfo.rangeIterator(slice.finish, slice.start) : delInfo.rangeIterator(slice.start, slice.finish); } private boolean nextSlice() { return ++sliceIdx < slices.length; } }; }
public void trim(ColumnFamily cf, int trimTo, long now) { // each cell can increment the count by at most one, so if we have fewer cells than trimTo, we // can skip trimming if (cf.getColumnCount() < trimTo) return; ColumnCounter counter = columnCounter(cf.getComparator(), now); Collection<Cell> cells = reversed ? cf.getReverseSortedColumns() : cf.getSortedColumns(); DeletionInfo.InOrderTester tester = cf.deletionInfo().inOrderTester(reversed); for (Iterator<Cell> iter = cells.iterator(); iter.hasNext(); ) { Cell cell = iter.next(); counter.count(cell, tester); if (counter.live() > trimTo) { iter.remove(); while (iter.hasNext()) { iter.next(); iter.remove(); } } } }
public void collectReducedColumns( ColumnFamily container, Iterator<Cell> reducedColumns, DecoratedKey key, int gcBefore, long now) { columnCounter = columnCounter(container.getComparator(), now); DeletionInfo.InOrderTester tester = container.deletionInfo().inOrderTester(reversed); while (reducedColumns.hasNext()) { Cell cell = reducedColumns.next(); if (logger.isTraceEnabled()) logger.trace( "collecting {} of {}: {}", columnCounter.live(), count, cell.getString(container.getComparator())); // An expired tombstone will be immediately discarded in memory, and needn't be counted. // Neither should be any cell shadowed by a range- or a partition tombstone. if (cell.getLocalDeletionTime() < gcBefore || !columnCounter.count(cell, tester)) continue; if (columnCounter.live() > count) break; if (respectTombstoneThresholds() && columnCounter.tombstones() > DatabaseDescriptor.getTombstoneFailureThreshold()) { Tracing.trace( "Scanned over {} tombstones; query aborted (see tombstone_failure_threshold); slices={}", DatabaseDescriptor.getTombstoneFailureThreshold(), getSlicesInfo(container)); throw new TombstoneOverwhelmingException( columnCounter.tombstones(), count, container.metadata().ksName, container.metadata().cfName, container.getComparator().getString(cell.name()), getSlicesInfo(container)); } container.appendColumn(cell); } boolean warnTombstones = logger.isWarnEnabled() && respectTombstoneThresholds() && columnCounter.tombstones() > DatabaseDescriptor.getTombstoneWarnThreshold(); if (warnTombstones) { String msg = String.format( "Read %d live and %d tombstone cells in %s.%s for key: %1.512s (see tombstone_warn_threshold). %d columns were requested, slices=%1.512s", columnCounter.live(), columnCounter.tombstones(), container.metadata().ksName, container.metadata().cfName, container.metadata().getKeyValidator().getString(key.getKey()), count, getSlicesInfo(container)); ClientWarn.warn(msg); logger.warn(msg); } Tracing.trace( "Read {} live and {} tombstone cells{}", columnCounter.live(), columnCounter.tombstones(), warnTombstones ? " (see tombstone_warn_threshold)" : ""); }
private static boolean isLive(ColumnFamily cf, IColumn c) { return c != null && !c.isMarkedForDelete() && !cf.deletionInfo().isDeleted(c); }