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);
 }
예제 #2
0
  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;
      }
    };
  }
예제 #3
0
  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();
        }
      }
    }
  }
예제 #4
0
  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);
 }