/** * Turns the given iterator into an update. * * @param iterator the iterator to turn into updates. * @param filter the column filter used when querying {@code iterator}. This is used to make * sure we don't include data for which the value has been skipped while reading (as we would * then be writing something incorrect). * * Warning: this method does not close the provided iterator, it is up to * the caller to close it. */ public static PartitionUpdate fromIterator(UnfilteredRowIterator iterator, ColumnFilter filter) { iterator = UnfilteredRowIterators.withOnlyQueriedData(iterator, filter); Holder holder = build(iterator, 16); MutableDeletionInfo deletionInfo = (MutableDeletionInfo) holder.deletionInfo; return new PartitionUpdate(iterator.metadata(), iterator.partitionKey(), holder, deletionInfo, false); }
/** * For an update on a counter table, returns a list containing a {@code CounterMark} for * every counter contained in the update. * * @return a list with counter marks for every counter in this update. */ public List<CounterMark> collectCounterMarks() { assert metadata().isCounter(); maybeBuild(); // We will take aliases on the rows of this update, and update them in-place. So we should be sure the // update is now immutable for all intent and purposes. canReOpen = false; List<CounterMark> marks = new ArrayList<>(); addMarksForRow(staticRow(), marks); for (Row row : this) addMarksForRow(row, marks); return marks; }
public void addPartitionDeletion(DeletionTime deletionTime) { assertNotBuilt(); deletionInfo.add(deletionTime); }
/** * Transaction for updates on the write path. */ public UpdateTransaction newUpdateTransaction(PartitionUpdate update, OpOrder.Group opGroup, int nowInSec) { if (!hasIndexes()) return UpdateTransaction.NO_OP; Index.Indexer[] indexers = indexes.values().stream() .map(i -> i.indexerFor(update.partitionKey(), update.columns(), nowInSec, opGroup, IndexTransaction.Type.UPDATE)) .filter(Objects::nonNull) .toArray(Index.Indexer[]::new); return indexers.length == 0 ? UpdateTransaction.NO_OP : new WriteTimeTransaction(indexers); }
/** * Merges the provided updates, yielding a new update that incorporates all those updates. * * @param updates the collection of updates to merge. This shouldn't be empty. * * @return a partition update that include (merge) all the updates from {@code updates}. */ public static PartitionUpdate merge(List<PartitionUpdate> updates) { assert !updates.isEmpty(); final int size = updates.size(); if (size == 1) return Iterables.getOnlyElement(updates); int nowInSecs = FBUtilities.nowInSeconds(); List<UnfilteredRowIterator> asIterators = Lists.transform(updates, AbstractBTreePartition::unfilteredIterator); return fromIterator(UnfilteredRowIterators.merge(asIterators, nowInSecs), ColumnFilter.all(updates.get(0).metadata())); }
updater.reset(); if (!update.deletionInfo().getPartitionDeletion().isLive()) indexer.onPartitionDeletion(update.deletionInfo().getPartitionDeletion()); if (update.deletionInfo().hasRanges()) update.deletionInfo().rangeIterator(false).forEachRemaining(indexer::onRangeTombstone); if (update.deletionInfo().mayModify(current.deletionInfo)) inputDeletionInfoCopy = update.deletionInfo().copy(HeapAllocator.instance); PartitionColumns columns = update.columns().mergeTo(current.columns); Row newStatic = update.staticRow(); Row staticRow = newStatic.isEmpty() ? current.staticRow : (current.staticRow.isEmpty() ? updater.apply(newStatic) : updater.apply(current.staticRow, newStatic)); Object[] tree = BTree.update(current.tree, update.metadata().comparator, update, update.rowCount(), updater); EncodingStats newStats = current.stats.mergeWith(update.stats());
DeletionInfo deletionInfo = updates.deletionInfo(); CFMetaData metadata = updates.metadata(); DecoratedKey key = updates.partitionKey();
private static PartitionUpdate deserialize30(DataInputPlus in, int version, SerializationHelper.Flag flag) throws IOException { CFMetaData metadata = CFMetaData.serializer.deserialize(in, version); UnfilteredRowIteratorSerializer.Header header = UnfilteredRowIteratorSerializer.serializer.deserializeHeader(metadata, null, in, version, flag); if (header.isEmpty) return emptyUpdate(metadata, header.key); assert !header.isReversed; assert header.rowEstimate >= 0; MutableDeletionInfo.Builder deletionBuilder = MutableDeletionInfo.builder(header.partitionDeletion, metadata.comparator, false); BTree.Builder<Row> rows = BTree.builder(metadata.comparator, header.rowEstimate); rows.auto(false); try (UnfilteredRowIterator partition = UnfilteredRowIteratorSerializer.serializer.deserialize(in, version, metadata, flag, header)) { while (partition.hasNext()) { Unfiltered unfiltered = partition.next(); if (unfiltered.kind() == Unfiltered.Kind.ROW) rows.add((Row)unfiltered); else deletionBuilder.add((RangeTombstoneMarker)unfiltered); } } MutableDeletionInfo deletionInfo = deletionBuilder.build(); return new PartitionUpdate(metadata, header.key, new Holder(header.sHeader.columns(), rows.build(), deletionInfo, header.staticRow, header.sHeader.stats()), deletionInfo, false); }
return; assertNotBuilt(); assert columns().statics.containsAll(row.columns()) : columns().statics + " is not superset of " + row.columns(); Row staticRow = holder.staticRow.isEmpty() ? row assert columns().regulars.containsAll(row.columns()) : columns().regulars + " is not superset of " + row.columns(); rowBuilder.add(row);
private PartitionUpdate update(int i) { if (repairs[i] == null) repairs[i] = new PartitionUpdate(command.metadata(), partitionKey, columns, 1); return repairs[i]; }
/** * Creates a partition update that entirely deletes a given partition. * * @param metadata the metadata for the created update. * @param key the partition key for the partition that the created update should delete. * @param timestamp the timestamp for the deletion. * @param nowInSec the current time in seconds to use as local deletion time for the partition deletion. * * @return the newly created partition deletion update. */ public static PartitionUpdate fullPartitionDelete(CFMetaData metadata, ByteBuffer key, long timestamp, int nowInSec) { return fullPartitionDelete(metadata, metadata.decorateKey(key), timestamp, nowInSec); }
private static PartitionUpdate deserializePre30(DataInputPlus in, int version, SerializationHelper.Flag flag, ByteBuffer key) throws IOException { try (UnfilteredRowIterator iterator = LegacyLayout.deserializeLegacyPartition(in, version, flag, key)) { assert iterator != null; // This is only used in mutation, and mutation have never allowed "null" column families return PartitionUpdate.fromIterator(iterator, ColumnFilter.all(iterator.metadata())); } }
/** * If a partition update has been read (and is thus unmodifiable), a call to this method * makes the update modifiable again. * <p> * Please note that calling this method won't result in optimal behavior in the sense that * even if very little is added to the update after this call, the whole update will be sorted * again on read. This should thus be used sparingly (and if it turns that we end up using * this often, we should consider optimizing the behavior). */ public synchronized void allowNewUpdates() { if (!canReOpen) throw new IllegalStateException("You cannot do more updates on collectCounterMarks has been called"); // This is synchronized to make extra sure things work properly even if this is // called concurrently with sort() (which should be avoided in the first place, but // better safe than sorry). isBuilt = false; if (rowBuilder == null) rowBuilder = builder(16); }
public void applyUpdates(FilteredPartition current, PartitionUpdate updates) throws InvalidRequestException { Map<DecoratedKey, Partition> map = stmt.requiresRead() ? Collections.<DecoratedKey, Partition>singletonMap(key, current) : null; UpdateParameters params = new UpdateParameters(cfm, updates.columns(), options, timestamp, stmt.getTimeToLive(options), map); stmt.addUpdateForKey(updates, clustering, params); } }
public static Commit newPrepare(DecoratedKey key, CFMetaData metadata, UUID ballot) { return new Commit(ballot, PartitionUpdate.emptyUpdate(metadata, key)); }
private void maybeBuild() { if (isBuilt) return; build(); }
updater.reset(); if (!update.deletionInfo().getPartitionDeletion().isLive()) indexer.onPartitionDeletion(update.deletionInfo().getPartitionDeletion()); if (update.deletionInfo().hasRanges()) update.deletionInfo().rangeIterator(false).forEachRemaining(indexer::onRangeTombstone); if (update.deletionInfo().mayModify(current.deletionInfo)) inputDeletionInfoCopy = update.deletionInfo().copy(HeapAllocator.instance); PartitionColumns columns = update.columns().mergeTo(current.columns); Row newStatic = update.staticRow(); Row staticRow = newStatic.isEmpty() ? current.staticRow : (current.staticRow.isEmpty() ? updater.apply(newStatic) : updater.apply(current.staticRow, newStatic)); Object[] tree = BTree.update(current.tree, update.metadata().comparator, update, update.rowCount(), updater); EncodingStats newStats = current.stats.mergeWith(update.stats());
DeletionInfo deletionInfo = updates.deletionInfo(); CFMetaData metadata = updates.metadata(); DecoratedKey key = updates.partitionKey();
/** * Transaction for updates on the write path. */ public UpdateTransaction newUpdateTransaction(PartitionUpdate update, OpOrder.Group opGroup, int nowInSec) { if (!hasIndexes()) return UpdateTransaction.NO_OP; Index.Indexer[] indexers = indexes.values().stream() .map(i -> i.indexerFor(update.partitionKey(), update.columns(), nowInSec, opGroup, IndexTransaction.Type.UPDATE)) .filter(Objects::nonNull) .toArray(Index.Indexer[]::new); return indexers.length == 0 ? UpdateTransaction.NO_OP : new WriteTimeTransaction(indexers); }
/** * Merges the provided updates, yielding a new update that incorporates all those updates. * * @param updates the collection of updates to merge. This shouldn't be empty. * * @return a partition update that include (merge) all the updates from {@code updates}. */ public static PartitionUpdate merge(List<PartitionUpdate> updates) { assert !updates.isEmpty(); final int size = updates.size(); if (size == 1) return Iterables.getOnlyElement(updates); int nowInSecs = FBUtilities.nowInSeconds(); List<UnfilteredRowIterator> asIterators = Lists.transform(updates, AbstractBTreePartition::unfilteredIterator); return fromIterator(UnfilteredRowIterators.merge(asIterators, nowInSecs), ColumnFilter.all(updates.get(0).metadata())); }