Search in sources :

Example 51 with AttributeUpdate

use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.

the class SegmentMetadataUpdateTransaction method preProcessAttributes.

/**
 * Pre-processes a collection of attributes.
 * After this method returns, all AttributeUpdates in the given collection will have the actual (and updated) value
 * of that attribute in the Segment.
 *
 * @param attributeUpdates The Updates to process (if any).
 * @throws BadAttributeUpdateException        If any of the given AttributeUpdates is invalid given the current state
 *                                            of the segment.
 * @throws AttributeIdLengthMismatchException If the given AttributeUpdates contains extended Attributes with the
 *                                            wrong length (compared to that which is defined on the Segment).
 * @throws MetadataUpdateException            If the operation cannot not be processed because a Metadata Update
 *                                            precondition check failed.
 */
private void preProcessAttributes(AttributeUpdateCollection attributeUpdates) throws BadAttributeUpdateException, MetadataUpdateException {
    if (attributeUpdates == null) {
        return;
    }
    // Make sure that the number of existing ExtendedAttributes + incoming ExtendedAttributes does not exceed the limit.
    if (type.isTransientSegment() && this.baseAttributeValues.size() > TRANSIENT_ATTRIBUTE_LIMIT) {
        throw new MetadataUpdateException(this.containerId, String.format("A Transient Segment ('%s') may not exceed %s Extended Attributes.", this.name, TRANSIENT_ATTRIBUTE_LIMIT));
    }
    // We must ensure that we aren't trying to set/update attributes that are incompatible with this Segment.
    validateAttributeIdLengths(attributeUpdates);
    for (AttributeUpdate u : attributeUpdates) {
        if (Attributes.isUnmodifiable(u.getAttributeId())) {
            throw new MetadataUpdateException(this.containerId, String.format("Attribute Id '%s' on Segment Id %s ('%s') may not be modified.", u.getAttributeId(), this.id, this.name));
        }
        AttributeUpdateType updateType = u.getUpdateType();
        boolean hasValue = false;
        long previousValue = Attributes.NULL_ATTRIBUTE_VALUE;
        if (this.attributeUpdates.containsKey(u.getAttributeId())) {
            hasValue = true;
            previousValue = this.attributeUpdates.get(u.getAttributeId());
        } else if (this.baseAttributeValues.containsKey(u.getAttributeId())) {
            hasValue = true;
            previousValue = this.baseAttributeValues.get(u.getAttributeId());
        }
        // Perform validation, and set the AttributeUpdate.value to the updated value, if necessary.
        switch(updateType) {
            case ReplaceIfGreater:
                // Verify value against existing value, if any.
                if (hasValue && u.getValue() <= previousValue) {
                    throw new BadAttributeUpdateException(this.name, u, false, String.format("Expected greater than '%s'.", previousValue));
                }
                break;
            case ReplaceIfEquals:
                // Verify value against existing value, if any.
                if (u.getComparisonValue() != previousValue || !hasValue) {
                    throw new BadAttributeUpdateException(this.name, u, !hasValue, String.format("Expected '%s', given '%s'.", previousValue, u.getComparisonValue()));
                }
                break;
            case None:
                // Verify value is not already set.
                if (hasValue) {
                    throw new BadAttributeUpdateException(this.name, u, false, String.format("Attribute value already set (%s).", previousValue));
                }
                break;
            case Accumulate:
                if (hasValue) {
                    u.setValue(previousValue + u.getValue());
                }
                break;
            case Replace:
                break;
            default:
                throw new BadAttributeUpdateException(this.name, u, !hasValue, "Unexpected update type: " + updateType);
        }
    }
    // Evaluate and set DynamicAttributeUpdates.
    for (DynamicAttributeUpdate u : attributeUpdates.getDynamicAttributeUpdates()) {
        u.setValue(u.getValueReference().evaluate(this));
    }
}
Also used : AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) DynamicAttributeUpdate(io.pravega.segmentstore.contracts.DynamicAttributeUpdate) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) BadAttributeUpdateException(io.pravega.segmentstore.contracts.BadAttributeUpdateException) DynamicAttributeUpdate(io.pravega.segmentstore.contracts.DynamicAttributeUpdate)

Example 52 with AttributeUpdate

use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.

the class TableMetadataStore method initialize.

// region MetadataStore Implementation
@Override
public CompletableFuture<Void> initialize(Duration timeout) {
    Preconditions.checkState(!this.initialized.get(), "TableMetadataStore is already initialized.");
    // Invoke submitAssignment(), which will ensure that the Metadata Segment is mapped in memory and pinned.
    // If this is the first time we initialize the TableMetadataStore for this SegmentContainer, a new id will be
    // assigned to it.
    val attributes = new HashMap<>(TableAttributes.DEFAULT_VALUES);
    // Make sure we enable rollover for this segment.
    attributes.putAll(this.config.getDefaultCompactionAttributes());
    val attributeUpdates = attributes.entrySet().stream().map(e -> new AttributeUpdate(e.getKey(), AttributeUpdateType.None, e.getValue())).collect(Collectors.toList());
    // Container Metadata Segment is a System Table Segment. It is System, Internal, and Critical.
    val segmentType = SegmentType.builder().tableSegment().system().critical().internal().build();
    return submitAssignment(SegmentInfo.newSegment(this.metadataSegmentName, segmentType, attributeUpdates), true, timeout).thenAccept(segmentId -> {
        this.initialized.set(true);
        log.info("{}: Metadata Segment pinned. Name = '{}', Id = '{}'", this.traceObjectId, this.metadataSegmentName, segmentId);
    });
}
Also used : lombok.val(lombok.val) TableAttributes(io.pravega.segmentstore.contracts.tables.TableAttributes) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) TableStore(io.pravega.segmentstore.contracts.tables.TableStore) BiFunction(java.util.function.BiFunction) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Supplier(java.util.function.Supplier) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) ArrayView(io.pravega.common.util.ArrayView) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) SegmentType(io.pravega.segmentstore.contracts.SegmentType) Runnables(com.google.common.util.concurrent.Runnables) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Charsets(com.google.common.base.Charsets) NameUtils(io.pravega.shared.NameUtils) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) TimeoutTimer(io.pravega.common.TimeoutTimer) Executor(java.util.concurrent.Executor) NonNull(lombok.NonNull) Collection(java.util.Collection) lombok.val(lombok.val) TableExtensionConfig(io.pravega.segmentstore.server.tables.TableExtensionConfig) CompletionException(java.util.concurrent.CompletionException) Collectors(java.util.stream.Collectors) Slf4j(lombok.extern.slf4j.Slf4j) ByteArraySegment(io.pravega.common.util.ByteArraySegment) StreamSegmentExistsException(io.pravega.segmentstore.contracts.StreamSegmentExistsException) Preconditions(com.google.common.base.Preconditions) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) HashMap(java.util.HashMap)

Example 53 with AttributeUpdate

use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.

the class StreamSegmentAppendOperationTests method createAttributes.

static AttributeUpdateCollection createAttributes() {
    val result = new AttributeUpdateCollection();
    long currentValue = 0;
    for (AttributeUpdateType ut : AttributeUpdateType.values()) {
        result.add(new AttributeUpdate(AttributeId.uuid(Attributes.CORE_ATTRIBUTE_ID_PREFIX, ut.getTypeId()), ut, ++currentValue, currentValue));
        result.add(new AttributeUpdate(AttributeId.random(AttributeId.Variable.MAX_LENGTH), ut, ++currentValue, currentValue));
    }
    return result;
}
Also used : lombok.val(lombok.val) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType)

Example 54 with AttributeUpdate

use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.

the class ContainerTableExtensionImpl method createSegment.

// endregion
// region TableStore Implementation
@Override
public CompletableFuture<Void> createSegment(@NonNull String segmentName, SegmentType segmentType, TableSegmentConfig config, Duration timeout) {
    Exceptions.checkNotClosed(this.closed.get(), this);
    // Ensure at least a TableSegment type.
    segmentType = SegmentType.builder(segmentType).tableSegment().build();
    val attributes = new HashMap<>(TableAttributes.DEFAULT_VALUES);
    attributes.putAll(selectLayout(segmentName, segmentType).getNewSegmentAttributes(config));
    val attributeUpdates = attributes.entrySet().stream().map(e -> new AttributeUpdate(e.getKey(), AttributeUpdateType.None, e.getValue())).collect(Collectors.toList());
    logRequest("createSegment", segmentName, segmentType, config);
    return this.segmentContainer.createStreamSegment(segmentName, segmentType, attributeUpdates, timeout);
}
Also used : lombok.val(lombok.val) TableAttributes(io.pravega.segmentstore.contracts.tables.TableAttributes) TableSegmentConfig(io.pravega.segmentstore.contracts.tables.TableSegmentConfig) Getter(lombok.Getter) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) IteratorArgs(io.pravega.segmentstore.contracts.tables.IteratorArgs) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) SegmentType(io.pravega.segmentstore.contracts.SegmentType) IteratorItem(io.pravega.segmentstore.contracts.tables.IteratorItem) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) BadSegmentTypeException(io.pravega.segmentstore.contracts.BadSegmentTypeException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) TimeoutTimer(io.pravega.common.TimeoutTimer) NonNull(lombok.NonNull) Collection(java.util.Collection) lombok.val(lombok.val) AsyncIterator(io.pravega.common.util.AsyncIterator) Collectors(java.util.stream.Collectors) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) TableSegmentInfo(io.pravega.segmentstore.contracts.tables.TableSegmentInfo) SegmentContainer(io.pravega.segmentstore.server.SegmentContainer) VisibleForTesting(com.google.common.annotations.VisibleForTesting) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) WriterSegmentProcessor(io.pravega.segmentstore.server.WriterSegmentProcessor) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Collections(java.util.Collections) CacheManager(io.pravega.segmentstore.server.CacheManager) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) HashMap(java.util.HashMap)

Example 55 with AttributeUpdate

use of io.pravega.segmentstore.contracts.AttributeUpdate in project pravega by pravega.

the class FixedKeyLengthTableSegmentLayout method put.

@Override
CompletableFuture<List<Long>> put(@NonNull DirectSegmentAccess segment, @NonNull List<TableEntry> entries, long tableSegmentOffset, TimeoutTimer timer) {
    val segmentInfo = segment.getInfo();
    ensureSegmentType(segmentInfo.getName(), segmentInfo.getType());
    val segmentKeyLength = getSegmentKeyLength(segmentInfo);
    ensureValidKeyLength(segmentInfo.getName(), segmentKeyLength);
    val attributeUpdates = new AttributeUpdateCollection();
    int batchOffset = 0;
    val batchOffsets = new ArrayList<Integer>();
    boolean isConditional = false;
    for (val e : entries) {
        val key = e.getKey();
        Preconditions.checkArgument(key.getKey().getLength() == segmentKeyLength, "Entry Key Length for key `%s` incompatible with segment '%s' which requires key lengths of %s.", key, segmentInfo.getName(), segmentKeyLength);
        attributeUpdates.add(createIndexUpdate(key, batchOffset));
        isConditional |= key.hasVersion();
        batchOffsets.add(batchOffset);
        batchOffset += this.serializer.getUpdateLength(e);
    }
    logRequest("put", segmentInfo.getName(), isConditional, tableSegmentOffset, entries.size(), batchOffset);
    if (batchOffset > this.config.getMaxBatchSize()) {
        throw new UpdateBatchTooLargeException(batchOffset, this.config.getMaxBatchSize());
    }
    // Update total number of entries in Table (this includes updates to the same key).
    attributeUpdates.add(new AttributeUpdate(TableAttributes.TOTAL_ENTRY_COUNT, AttributeUpdateType.Accumulate, entries.size()));
    val serializedEntries = this.serializer.serializeUpdate(entries);
    val append = tableSegmentOffset == TableSegmentLayout.NO_OFFSET ? segment.append(serializedEntries, attributeUpdates, timer.getRemaining()) : segment.append(serializedEntries, attributeUpdates, tableSegmentOffset, timer.getRemaining());
    return handleConditionalUpdateException(append, segmentInfo).thenApply(segmentOffset -> {
        this.compactionService.process(new CompactionCandidate(segment));
        return batchOffsets.stream().map(offset -> offset + segmentOffset).collect(Collectors.toList());
    });
}
Also used : lombok.val(lombok.val) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) DynamicAttributeValue(io.pravega.segmentstore.contracts.DynamicAttributeValue) TableSegmentConfig(io.pravega.segmentstore.contracts.tables.TableSegmentConfig) SneakyThrows(lombok.SneakyThrows) RequiredArgsConstructor(lombok.RequiredArgsConstructor) RevisionDataInput(io.pravega.common.io.serialization.RevisionDataInput) IteratorArgs(io.pravega.segmentstore.contracts.tables.IteratorArgs) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) ArrayView(io.pravega.common.util.ArrayView) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) BufferView(io.pravega.common.util.BufferView) Duration(java.time.Duration) Map(java.util.Map) RevisionDataOutput(io.pravega.common.io.serialization.RevisionDataOutput) AsyncReadResultProcessor(io.pravega.segmentstore.server.reading.AsyncReadResultProcessor) VersionedSerializer(io.pravega.common.io.serialization.VersionedSerializer) Attributes(io.pravega.segmentstore.contracts.Attributes) TableKey(io.pravega.segmentstore.contracts.tables.TableKey) NonNull(lombok.NonNull) Collection(java.util.Collection) CompletionException(java.util.concurrent.CompletionException) DynamicAttributeUpdate(io.pravega.segmentstore.contracts.DynamicAttributeUpdate) Collectors(java.util.stream.Collectors) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) TableSegmentInfo(io.pravega.segmentstore.contracts.tables.TableSegmentInfo) ByteArraySegment(io.pravega.common.util.ByteArraySegment) Builder(lombok.Builder) DelayedProcessor(io.pravega.common.concurrent.DelayedProcessor) WriterSegmentProcessor(io.pravega.segmentstore.server.WriterSegmentProcessor) Futures(io.pravega.common.concurrent.Futures) TableAttributes(io.pravega.segmentstore.contracts.tables.TableAttributes) Getter(lombok.Getter) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) BadAttributeUpdateException(io.pravega.segmentstore.contracts.BadAttributeUpdateException) AtomicReference(java.util.concurrent.atomic.AtomicReference) BadKeyVersionException(io.pravega.segmentstore.contracts.tables.BadKeyVersionException) ArrayList(java.util.ArrayList) SegmentType(io.pravega.segmentstore.contracts.SegmentType) IteratorItem(io.pravega.segmentstore.contracts.tables.IteratorItem) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) AttributeIterator(io.pravega.segmentstore.server.AttributeIterator) StreamSegmentTruncatedException(io.pravega.segmentstore.contracts.StreamSegmentTruncatedException) IteratorState(io.pravega.segmentstore.contracts.tables.IteratorState) TimeoutTimer(io.pravega.common.TimeoutTimer) KeyNotExistsException(io.pravega.segmentstore.contracts.tables.KeyNotExistsException) AttributeId(io.pravega.segmentstore.contracts.AttributeId) lombok.val(lombok.val) AsyncIterator(io.pravega.common.util.AsyncIterator) IOException(java.io.IOException) Beta(com.google.common.annotations.Beta) ObjectBuilder(io.pravega.common.ObjectBuilder) DirectSegmentAccess(io.pravega.segmentstore.server.DirectSegmentAccess) AttributeUpdateCollection(io.pravega.segmentstore.contracts.AttributeUpdateCollection) Data(lombok.Data) Preconditions(com.google.common.base.Preconditions) AttributeUpdateType(io.pravega.segmentstore.contracts.AttributeUpdateType) AllArgsConstructor(lombok.AllArgsConstructor) TableEntry(io.pravega.segmentstore.contracts.tables.TableEntry) Collections(java.util.Collections) AttributeUpdate(io.pravega.segmentstore.contracts.AttributeUpdate) DynamicAttributeUpdate(io.pravega.segmentstore.contracts.DynamicAttributeUpdate) ArrayList(java.util.ArrayList)

Aggregations

AttributeUpdate (io.pravega.segmentstore.contracts.AttributeUpdate)71 lombok.val (lombok.val)51 AttributeUpdateCollection (io.pravega.segmentstore.contracts.AttributeUpdateCollection)36 ArrayList (java.util.ArrayList)34 HashMap (java.util.HashMap)34 Test (org.junit.Test)32 AttributeId (io.pravega.segmentstore.contracts.AttributeId)31 AttributeUpdateType (io.pravega.segmentstore.contracts.AttributeUpdateType)31 CompletableFuture (java.util.concurrent.CompletableFuture)30 BadAttributeUpdateException (io.pravega.segmentstore.contracts.BadAttributeUpdateException)25 DynamicAttributeUpdate (io.pravega.segmentstore.contracts.DynamicAttributeUpdate)24 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)24 Collection (java.util.Collection)24 Collections (java.util.Collections)24 Map (java.util.Map)24 Attributes (io.pravega.segmentstore.contracts.Attributes)23 Duration (java.time.Duration)23 Exceptions (io.pravega.common.Exceptions)22 Collectors (java.util.stream.Collectors)22 Cleanup (lombok.Cleanup)22