Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: add proposal for new return type

...

The proposed return type from get(key, asOfTimestamp) of ValueAndTimestamp<V> represents returning the record value and timestamp (i.e., validFrom timestamp) found for the given key (and timestamp bound). In some situations, it may be useful for users to additionally have the validTo timestamp associated with the record. In order to provide this additional timestamp to users, the return type of get(key, asOfTimestamp) could instead be a new type, e.g., VersionedRecord , which has a value and two associated timestamps. This again complicates the interface and diverges the return types of get(key)  and get(key, asOfTimestamp) . (It's not meaningful to return a validTo timestamp associated with records returned from get(key) since the validTo timestamp will always be a sentinel value that signals that the record is the latest record associated with the given key.)

Alternatively, if we want to leave the door open to supporting additional return timestamps in the future while not diverging the return types of get(key)  and get(key, asOfTimestamp) , we can introduce a new type to use the return type of both methods, e.g., VersionedValue<V>  or RecordVersion<V> , which today looks the same as ValueAndTimestamp<V>  but can have additional fields in the future:

Code Block
package org.apache.kafka.streams.state;

/**
 * Combines a value from a {@link KeyValue} with a timestamp, for use as the return type 
 * from {@link VersionedKeyValueStore#get(Object, long)} and related methods.
 *
 * @param <V> The value type
 */
public final class VersionedValue<V> {
    private final V value;
    private final long timestamp;

    private VersionedValue(final V value, final long timestamp) {
        this.value = Objects.requireNonNull(value);
        this.timestamp = timestamp;
    }

    /**
     * Create a new {@link VersionedValue} instance. {@code value} cannot be {@code null}.
     *
     * @param value      the value
     * @param timestamp  the timestamp
     * @param <V> the type of the value
     * @return a new {@link VersionedValue} instance
     */
    public static <V> VersionedValue<V> make(final V value, final long timestamp) {
        if (value == null) {
            throw new IllegalArgumentException("value cannot be null");
        }
        return new VersionedValue<>(value, timestamp);
    }

    public V value() {
        return value;
    }

    public long timestamp() {
        return timestamp;
    }

    @Override
    public String toString() {
        return "<" + value + "," + timestamp + ">";
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final VersionedValue<?> that = (VersionedValue<?>) o;
        return timestamp == that.timestamp &&
            Objects.equals(value, that.value);
    }

    @Override
    public int hashCode() {
        return Objects.hash(value, timestamp);
    }
}

Return null with timestamp from get()

...