Hi Alieh,

I agree with Bruno that a weaker guarantee could be useful already,
and it's anyway possible to strengthen the guarantees later on. On the
other hand, it would be nice to provide a consistent view across all
segments if it doesn't come with major downsides, because until now IQ
does provide a consistent view (via iterators), and this would be the
first feature that diverges from that guarantee.

I think a consistent could be achieved relatively easily by creating a
snapshot (https://github.com/facebook/rocksdb/wiki/Snapshot) that will
ensure a consistent view on a single DB and using
`ReadOptions.setSnapshot` for the gets. Since versioned state stores
segments seem to be backed by a single RocksDB instance (that was
unclear to me during our earlier discussion), a single snapshot should
be enough to guarantee a consistent view - we just need to make sure
to clean up the snapshots after use, similar to iterators. If we
instead need a consistent view across multiple RocksDB instances, we
may have to acquire a write lock on all of those (could use the
current object monitors of our `RocksDB` interface) for the duration
of creating snapshots across all instances - which I think would also
be permissible performance-wise. Snapshots are just a sequence number
and should be pretty lightweight to create (they have, however,
downside when it comes to compaction just like iterators).

With that in mind, I would be in favor of at least exploring the
option of using snapshots for a consistent view here, before dropping
this useful guarantee.

Cheers,
Lucas

On Tue, Nov 14, 2023 at 2:20 PM Bruno Cadonna <cado...@apache.org> wrote:
>
> Hi Alieh,
>
> Regarding the semantics/guarantees of the query type:
>
> Do we need a snapshot semantic or can we specify a weaker but still
> useful semantic?
>
> An option could be to guarantee that:
> 1. the query returns the latest version when the query arrived at the
> state store
> 2. the query returns a valid history, i.e., versions with adjacent and
> non-overlapping validity intervals.
>
> I think guarantee 1 is quite obvious. Guarantee 2 maybe needs some
> explanation. If we do not avoid writes to the state store during the
> processing of interactive queries, it might for example happen that the
> latest version in the state store moves to data structures that are
> responsible for older versions. In our RocksDB implementation that are
> the segments. Thus, it could be that during query processing Kafka
> Streams reads the latest value x and encounters again x in a segment
> because a processor put a newer version of x in the versioned state
> store. A similar scenario might also happen to earlier versions. If
> Streams does not account for such cases it could return invalid histories.
>
> Maybe such weaker guarantees are enough for most use cases.
>
> You could consider implementing weaker guarantees as I described and if
> there is demand propose stricter guarantees in a follow-up KIP.
>
> Maybe there are also other simpler guarantees that make sense.
>
> Best,
> Bruno
>
>
> On 11/9/23 12:30 PM, Bruno Cadonna wrote:
> > Hi,
> >
> > Thanks for the updates!
> >
> > First my take on previous comments:
> >
> >
> > 50)
> > I am in favor of deprecating the constructor that does not take the
> > validTo parameter. That implies that I am in favor of modifying get(key,
> > asOf) to set the correct validTo.
> >
> >
> > 60)
> > I am in favor of renaming ValueIterator to VersionedRecordIterator and
> > define it as:
> >
> > public interface VersionedRecordIterator<V> extends
> > Iterator<VersionedRecord<V>>
> >
> > (Matthias, you mixed up ValueAndTimestamp with VersionedRecord in your
> > last e-mail, didn't you? Just double-checking if I understood what you
> > are proposing.)
> >
> >
> > 70)
> > I agree with Matthias that adding a new method on the
> > VersionedKeyValueStore interface defeats the purpose of one of the goals
> > of IQv2, i.e., not to need to extend the state store interface for IQ. I
> > would say if we do not need the method in normal processing, we should
> > not extend the public state store interface. BTW, nobody forces you to
> > StoreQueryUtils. I think that internal utils class was introduced for
> > convenience to leverage existing methods on the state store interface.
> >
> >
> > 80)
> > Why do we limit ourselves by specifying a default order on the result?
> > Different state store implementation might have different strategies to
> > store the records which affects the order in which the records are
> > returned if they are not sorted before they are returned to the user.
> > Some users might not be interested in an order of the result and so
> > there is no reason those users pay the cost for sorting. I propose to
> > not specify a default order but sort the results (if needed) when
> > withDescendingX() and withAscendingX() is specified on the query object.
> >
> >
> > Regarding the snapshot guarantees for the iterators, I need to think a
> > bit more about it. I will come back to this thread in the next days.
> >
> >
> > Best,
> > Bruno
> >
> >
> > On 11/8/23 5:30 PM, Alieh Saeedi wrote:
> >> Thank you, Bruno and Matthias, for keeping the discussion going and for
> >> reviewing the PR.
> >>
> >> Here are the KIP updates:
> >>
> >>     - I removed the `peek()` from the `ValueIterator` interface since
> >> we do
> >>     not need it.
> >>     - Yes, Bruno, the `validTo` field in the `VersionedRecod` class is
> >>     exclusive. I updated the javadocs for that.
> >>
> >>
> >> Very important critical open questions. I list them here based on
> >> priority
> >> (descendingly).
> >>
> >>     - I implemented the `get(key, fromtime, totime)` method here
> >>
> >> <https://github.com/aliehsaeedii/kafka/blob/9578b7cb7cdade22cc63f671693f5aeb993937ca/streams/src/main/java/org/apache/kafka/streams/state/internals/RocksDBVersionedStore.java#L262>:
> >>     the problem is that this implementation does not guarantee
> >> consistency
> >>     because processing might continue interleaved (no snapshot
> >> semantics is
> >>     implemented). More over, it materializes all results in memory.
> >>        - Solution 1: Use a lock and release it after retrieving all
> >> desired
> >>        records from all segments.
> >>           - positive point: snapshot semantics is implemented
> >>           - negative points: 1) It is expensive since iterating over all
> >>           segments may take a long time. 2) It still requires
> >> materializing results
> >>           on memory
> >>        - Solution 2: use `RocksDbIterator`.
> >>           - positive points: 1) It guarantees snapshot segments. 2) It
> >> does
> >>           not require materializing results in memory.
> >>           - negative points: it is expensive because, anyway, we need to
> >>           iterate over all (many) segments.
> >>
> >>             Do you have any thoughts on this issue? (ref: Matthias's
> >> comment
> >> <https://github.com/apache/kafka/pull/14626#pullrequestreview-1709280589>)
> >>
> >>     - I added the field `validTo` in `VersionedRecord`. Its default
> >> value is
> >>     MAX. But as Matthias mentioned, for the single-key single-ts
> >>     (`VersionedKeyQuery` in KIP-960), it may not always be true. If the
> >>     returned record belongs to an old segment, maybe it is not valid
> >> any more.
> >>     So MAX is not the correct value for `ValidTo`. Two solutions come
> >> to mind:
> >>        - Solution 1: make the `ValidTo` as an `Optional` and set it to
> >>        `empty` for the retuned result of `get(key, asOfTimestamp)`.
> >>        - Solution 2: change the implementation of `get(key,
> >> asOfTimestamp)`
> >>        so that it finds the correct `validTo` for the returned
> >> versionedRecord.
> >>
> >>        - In this KIP and the next one, even though the default
> >> ordering is
> >>     with ascending ts, I added the method `withAscendingTimestamps()`
> >> to have
> >>     more user readibility (as Bruno suggested), while Hanyu did only add
> >>     `withDescending...` methods (he did not need ascending because
> >> that's the
> >>     default anyway). Matthias believes that we should not have
> >>     inconsistencies (he actually hates them:D). Shall I change my KIP
> >> or Hanyu?
> >>     Thoughts?
> >>
> >>
> >> That would be maybe helpful to look into the PR
> >> <https://github.com/apache/kafka/pull/14626> for more clarity and even
> >> review that ;-)
> >>
> >> Cheers,
> >> Alieh
> >>
> >> On Thu, Nov 2, 2023 at 7:13 PM Bruno Cadonna <cado...@apache.org> wrote:
> >>
> >>> Hi Alieh,
> >>>
> >>> First of all, I like the examples.
> >>>
> >>> Is validTo in VersionedRecord exclusive or inclusive?
> >>> In the javadocs you write:
> >>>
> >>> "@param validTo    the latest timestamp that value is valid"
> >>>
> >>> I think that is not true because the validity is defined by the start
> >>> time of the new version. The new and the old version cannot both be
> >>> valid at that same time.
> >>>
> >>> Theoretically, you could set validTo to the start time of the new
> >>> version - 1. However, what is the unit of the 1? Is it nanoseconds?
> >>> Milliseconds? Seconds? Sure we could agree on one, but I think it is
> >>> more elegant to just make the validTo exclusive. Actually, you used it
> >>> as exclusive in your examples.
> >>>
> >>>
> >>> Thanks for the KIP!
> >>>
> >>> Best,
> >>> Bruno
> >>>
> >>> On 11/1/23 9:01 PM, Alieh Saeedi wrote:
> >>>> Hi all,
> >>>> @Matthias: I think Victoria was right. I must add the method `get(key,
> >>>> fromTime, toTime)` to the interface `VersionedKeyValueStore`. Right
> >>>> now,
> >>>> having the method only in `RocksDBVersionedStore`, made me to have an
> >>>> instance of `RocksDBVersionedStore` (instead of
> >>>> `VersionedKeyValueStore`)
> >>>> in `StoreQueryUtils.runMultiVersionedKeyQuery()` method. In future, we
> >>> are
> >>>> going to use the same method for In-memory/SPDB/blaBla versioned
> >>>> stores.
> >>>> Then either this method won't work any more, or we have to add code (if
> >>>> clauses) for each type of versioned stores. What do you think about
> >>>> that?
> >>>>
> >>>> Bests,
> >>>> Alieh
> >>>>
> >>>> On Tue, Oct 24, 2023 at 10:01 PM Alieh Saeedi <asae...@confluent.io>
> >>> wrote:
> >>>>
> >>>>> Thank you, Matthias, Bruno, and Guozhang for keeping the discussion
> >>> going.
> >>>>>
> >>>>> Here is the list of changes I made:
> >>>>>
> >>>>>      1. I enriched the "Example" section as Bruno suggested. Do you
> >>> please
> >>>>>      have a look at that section? I think I devised an interesting one
> >>> ;-)
> >>>>>      2. As Matthias and Guozhang suggested, I renamed variables and
> >>> methods
> >>>>>      as follows:
> >>>>>         - "fromTimestamp" -> "fromTime"
> >>>>>         - "asOfTimestamp" -> "toTime"
> >>>>>         - "from(Instant fromTime)" -> "fromTime(Instant fromTime)"
> >>>>>         - "asOf(Instant toTime)" -> "toTime(Instant toTime)"
> >>>>>      3.
> >>>>>
> >>>>>      About throwing an NPE when time bounds are `null`: Ok,
> >>>>> Matthias, I
> >>> am
> >>>>>      convinced by your idea. I consider a null timestamp as "no
> >>>>> bound".
> >>> But I
> >>>>>      had to change KIP-960 and the corresponding PR to be
> >>>>> consistent as
> >>> well.
> >>>>>
> >>>>> Answering questions and some more discussion points:
> >>>>>
> >>>>>      1.
> >>>>>
> >>>>>      For now, I keep the class names as they are.
> >>>>>      2.
> >>>>>
> >>>>>      About the new field "validTo" in VersionedRecord. Yes Matthias I
> >>> keep
> >>>>>      the old constructor, which does not have `validTo` as an input
> >>> parameter.
> >>>>>      But in the body of the old constructor, I consider the default
> >>> value MAX
> >>>>>      for the validTo field. I think MAX must be the default value for
> >>> `validTo`
> >>>>>      since before inserting a tombstone or a new value for the same
> >>>>> key,
> >>> the
> >>>>>      value must be valid till iternity.
> >>>>>      3.
> >>>>>
> >>>>>      Regarding changing the ValueIterator interface from `public
> >>> interface
> >>>>>      ValueIterator<V> extends Iterator<V>` to `public interface
> >>>>>      ValueIterator<V> extends Iterator<VersionedRecord<V>>`:
> >>>>> Matthias, I
> >>> do not
> >>>>>      know how it improves type safety because the
> >>>>> MultiVersionedKeyQuery
> >>> class
> >>>>>      returns a ValueIterator of VersionedRecord any way. But if we
> >>>>> want
> >>> to be
> >>>>>      consistent with KeyValueIterator, we must apply the changes you
> >>> suggested.
> >>>>>      4.
> >>>>>
> >>>>>      Regarding adding the new `get(key, fromTime, toTime)` method
> >>>>> to the
> >>>>>      public interface `VersionedKeyValueStore` or only adding it to
> >>>>> the
> >>>>>      class `RocksDBVersionedStore`: In the KIP, I changed the
> >>>>> interface
> >>> as
> >>>>>      Victoria suggested. But still, I am not convinced why we do that.
> >>> @Victoria:
> >>>>>      Do you please clarify why we have to define it in the interface?
> >>> More
> >>>>>      specifically, why do we need to use generic
> >>>>> VersionedKeyValueStore
> >>>>>      instead of simply using the implementing classes?
> >>>>>
> >>>>> Cheers,
> >>>>> Alieh
> >>>>>
> >>>>> On Sat, Oct 14, 2023 at 3:35 AM Guozhang Wang <
> >>> guozhang.wang...@gmail.com>
> >>>>> wrote:
> >>>>>
> >>>>>> Thanks Alieh for the KIP, as well as a nice summary of all the
> >>>>>> discussions! Just my 2c regarding your open questions:
> >>>>>>
> >>>>>> 1. I just checked KIP-889
> >>>>>> (
> >>>>>>
> >>> https://cwiki.apache.org/confluence/display/KAFKA/KIP-889%3A+Versioned+State+Stores
> >>>>>> )
> >>>>>> and we used "VersionedRecord<V> get(K key, long asOfTimestamp);",
> >>>>>> so I
> >>>>>> feel to be consistent with this API is better compared with being
> >>>>>> consistent with "WindowKeyQuery"?
> >>>>>>
> >>>>>> 3. I agree with Matthias that naming is always tricky, and I also
> >>>>>> tend
> >>>>>> to be consistent with what we already have (even if in retro it may
> >>>>>> not be the best idea :P and if that was really becoming a complaint,
> >>>>>> we would change it across the board in one shot as well later).
> >>>>>>
> >>>>>> Guozhang
> >>>>>>
> >>>>>> On Wed, Oct 11, 2023 at 9:12 PM Matthias J. Sax <mj...@apache.org>
> >>> wrote:
> >>>>>>>
> >>>>>>> Thanks for the update!
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> Some thoughts about changes you made and open questions you raised:
> >>>>>>>
> >>>>>>>
> >>>>>>> 10) About asOf vs until: I was just looking into `WindowKeyQuery`,
> >>>>>>> `WindowRangeQuery` and also `ReadOnlyWindowStore` interfaces. For
> >>> those,
> >>>>>>> we use "timeFrom" and "timeTo", so it seems best to actually use
> >>>>>>> `to(Instant toTime)` to keep the naming consistent across the board?
> >>>>>>>
> >>>>>>> If yes, we should also do `from (Instant fromTime)` and use getters
> >>>>>>> `fromTime()` and `toTime()` -- given that it's range bounds it seems
> >>>>>>> acceptable to me, to diverge a little bit from KIP-960
> >>> `asOfTimestamp()`
> >>>>>>> -- but we could also rename it to `asOfTime()`? -- Given that we
> >>>>>>> strongly type with `Instant` I am not worried about semantic
> >>> ambiguity.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 20) About throwing a NPE when time bounds are `null` -- why? (For
> >>>>>>> the
> >>>>>>> key it makes sense as is mandatory to have a key.) Could we not
> >>>>>>> interpret `null` as "no bound". We did KIP-941 to add `null` for
> >>>>>>> open-ended `RangeQueries`, so I am wondering if we should just stick
> >>> to
> >>>>>>> the same semantics?
> >>>>>>>
> >>>>>>> Cf
> >>>>>>>
> >>>>>>
> >>> https://cwiki.apache.org/confluence/display/KAFKA/KIP-941%3A+Range+queries+to+accept+null+lower+and+upper+bounds
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 30) About the class naming. That's always tricky, and I am not
> >>>>>>> married
> >>>>>>> to my proposal. I agree with Bruno that the other suggested names
> >>>>>>> are
> >>>>>>> not really better. -- The underlying idea was, to get some
> >>> "consistent"
> >>>>>>> naming across the board.
> >>>>>>>
> >>>>>>> Existing `KeyQuery`
> >>>>>>> New `VersionedKeyQuery` (KIP-960; we add a prefix)
> >>>>>>> New `MultiVersionKeyQuery` (this KIP; extend the prefix with a
> >>>>>> pre-prefix)
> >>>>>>>
> >>>>>>> Existing `RangeQuery`
> >>>>>>> New `MultiVersionRangeQuery` (KIP-969; add same prefix as above)
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 40) I am fine with not adding `range(from, to)` -- it was just an
> >>> idea.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> Some more follow up question:
> >>>>>>>
> >>>>>>> 50) You propose to add a new constructor and getter to
> >>> `VersionedRecord`
> >>>>>>> -- I am wondering if this implies that `validTo` is optional because
> >>> the
> >>>>>>> existing constructor is not deprecated? -- Also, what happens if
> >>>>>>> `validTo` is not set and `valueTo()` is called? Or do we intent to
> >>> make
> >>>>>>> `validTo` mandatory?
> >>>>>>>
> >>>>>>> Maybe this question can only be answered when working on the code,
> >>> but I
> >>>>>>> am wondering if we should make `validTo` mandatory or not... And
> >>>>>>> what
> >>>>>>> the "blast radius" of changing `VersionedRecord` will be in general.
> >>> Do
> >>>>>>> you have already some POC PR that we could look at to get some
> >>>>>>> signals
> >>>>>>> about this?
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 60) The new query class is defined to return
> >>>>>>> `ValueIterator<VersionedRecord<V>>` -- while I like the idea to add
> >>>>>>> `ValueIterator<V>` in a generic way on the one hand, I am
> >>>>>>> wondering if
> >>>>>>> it might be better to change it, and enforce its usage (ie, return
> >>> type)
> >>>>>>> of `VersionedRecord` to improve type safety (type erasure is often a
> >>>>>>> pain, and we could mitigate it this way).
> >>>>>>>
> >>>>>>> Btw: We actually do a similar thing for `KeyValueIterator`.
> >>>>>>>
> >>>>>>> Ie,
> >>>>>>>
> >>>>>>> public interface ValueIterator<V> extends
> >>> Iterator<ValueAndTimestamp<V>>
> >>>>>>>
> >>>>>>> and
> >>>>>>>
> >>>>>>> ValueAndTimestamp<V> peek();
> >>>>>>>
> >>>>>>> This would imply that the return type of the new query is
> >>>>>>> `ValueIterator<V>` on the interface what seems simpler and more
> >>> elegant?
> >>>>>>>
> >>>>>>> If we go with the change, I am also wondering if we need to find a
> >>>>>>> better name for the new iterator class? Maybe `VersionIterator` or
> >>>>>>> something like this?
> >>>>>>>
> >>>>>>> Of course it might limit the use of `ValueIterator` for other value
> >>>>>>> types -- not sure if this a limitation that is prohibitive? My gut
> >>>>>>> feeling is, that is should not be too limiting.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 70) Do we really need the change in `VersionedKeyValueStore` and
> >>>>>>> add a
> >>>>>>> new method? In the end, the idea of IQv2 is to avoid exactly this...
> >>> It
> >>>>>>> was the main issue for IQv1, that the base interface of the store
> >>> needed
> >>>>>>> an update and thus all classed implementing the base interface,
> >>>>>>> making
> >>>>>>> it very cumbersome to add new query types. -- Of course, we need
> >>>>>>> this
> >>>>>>> new method on the actually implementation (as private method)
> >>>>>>> that can
> >>>>>>> be called from `query()` method, but adding it to the interface
> >>>>>>> seems
> >>> to
> >>>>>>> defeat the purpose of IQv2.
> >>>>>>>
> >>>>>>> Note, for existing IQv2 queries types that go against others stores,
> >>> the
> >>>>>>> public methods already existed when IQv2 was introduces, and thus
> >>>>>>> the
> >>>>>>> implementation of these query types just pragmatically re-used
> >>> existing
> >>>>>>> methods -- but it does not imply that new public method should be
> >>> added.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> -Matthias
> >>>>>>>
> >>>>>>>
> >>>>>>> On 10/11/23 5:11 AM, Bruno Cadonna wrote:
> >>>>>>>> Thanks for the updates, Alieh!
> >>>>>>>>
> >>>>>>>> The example in the KIP uses the allVersions() method which we
> >>>>>>>> agreed
> >>>>>> to
> >>>>>>>> remove.
> >>>>>>>>
> >>>>>>>> Regarding your questions:
> >>>>>>>> 1. asOf vs. until: I am fine with both but slightly prefer until.
> >>>>>>>> 2. What about KeyMultiVersionsQuery, KeyVersionsQuery (KIP-960
> >>>>>>>> would
> >>>>>>>> then be KeyVersionQuery). However, I am also fine with
> >>>>>>>> MultiVersionedKeyQuery since none of the names sounds better or
> >>>>>>>> worse
> >>>>>> to
> >>>>>>>> me.
> >>>>>>>> 3. I agree with you not to introduce the method with the two bounds
> >>> to
> >>>>>>>> keep things simple.
> >>>>>>>> 4. Forget about fromTime() an asOfTime(), from() and asOf() is
> >>>>>>>> fine.
> >>>>>>>> 5. The main purpose is to show how to use the API. Maybe make an
> >>>>>> example
> >>>>>>>> with just the key to distinguish this query from the single value
> >>>>>> query
> >>>>>>>> of KIP-960 and then one with a key and a time range. When you
> >>>>>>>> iterate
> >>>>>>>> over the results you could also call validTo(). Maybe add some
> >>>>>>>> actual
> >>>>>>>> records in the comments to show what the result might look like.
> >>>>>>>>
> >>>>>>>> Regarding the test plan, I hope you also plan to add unit tests in
> >>> all
> >>>>>>>> of your KIPs. Maybe you could also explain why system tests are not
> >>>>>>>> needed here.
> >>>>>>>>
> >>>>>>>> Best,
> >>>>>>>> Bruno
> >>>>>>>>
> >>>>>>>> On 10/10/23 5:36 PM, Alieh Saeedi wrote:
> >>>>>>>>> Thank you all for the very exact and constructive comments. I
> >>>>>>>>> really
> >>>>>>>>> enjoyed reading your ideas and all the important points you
> >>>>>>>>> made me
> >>>>>> aware
> >>>>>>>>> of. I updated KIP-968 as follows:
> >>>>>>>>>
> >>>>>>>>>       1. If the key or time bounds are null, the method returns
> >>>>>>>>> NPE.
> >>>>>>>>>       2. The "valid" word: I removed the sentence "all the records
> >>>>>> that are
> >>>>>>>>>       valid..." and replaced it with an exact explanation. More
> >>> over, I
> >>>>>>>>> explained
> >>>>>>>>>       it with an example in the KIP but not in the javadocs. Do I
> >>> need
> >>>>>>>>> to add the
> >>>>>>>>>       example to the javadocs as well?
> >>>>>>>>>       3. Since I followed Bruno's suggestion and removed the
> >>>>>> allVersions()
> >>>>>>>>>       method, the problem of meaningless combinations is
> >>>>>>>>> solved, and
> >>> I
> >>>>>>>>> do not
> >>>>>>>>>       need any IllegalArgumentException or something like that.
> >>>>>>>>> Therefore, the
> >>>>>>>>>       change is that if no time bound is specified, the query
> >>>>>>>>> returns
> >>>>>>>>> the records
> >>>>>>>>>       with the specified key for all timestamps (all versions).
> >>>>>>>>>       4. As Victoria suggested, adding a method to the
> >>>>>>>>> *VersionedKeyValueStore
> >>>>>>>>>       *interface is essential. So I did that. I had this method
> >>>>>>>>> only
> >>>>>> in the
> >>>>>>>>>       RocksDBVersionedStore class, which was not enough.
> >>>>>>>>>       5. I added the *validTo* field to the VersionedRecord
> >>>>>>>>> class to
> >>> be
> >>>>>>>>> able
> >>>>>>>>>       to represent the tombstones. As you suggested, we postpone
> >>>>>> solving
> >>>>>>>>> the
> >>>>>>>>>       problem of retrieving consecutive tombstones for later.
> >>>>>>>>>       6. I added the "Test Plan" section to all KIPs. I hope
> >>>>>>>>> what I
> >>>>>>>>> wrote is
> >>>>>>>>>       convincing.
> >>>>>>>>>       7. I added the *withAscendingTimestamp()* method to provide
> >>> more
> >>>>>>>>> code readability
> >>>>>>>>>       for the user.
> >>>>>>>>>       8. I removed the evil word "get" from all getter methods.
> >>>>>>>>>
> >>>>>>>>> There have also been some more suggestions which I am still not
> >>>>>> convinced
> >>>>>>>>> or clear about them:
> >>>>>>>>>
> >>>>>>>>>       1. Regarding asOf vs until: reading all comments, my
> >>>>>>>>> conclusion
> >>>>>>>>> was that
> >>>>>>>>>       I keep it as "asOf" (following Walker's idea as the native
> >>>>>> speaker
> >>>>>>>>> as well
> >>>>>>>>>       as Bruno's suggestion to be consistent with
> >>> single-key_single_ts
> >>>>>>>>> queries).
> >>>>>>>>>       But I do not have a personal preference. If you insist on
> >>>>>> "until",
> >>>>>>>>> I change
> >>>>>>>>>       it.
> >>>>>>>>>       2. Bruno suggested renaming the class
> >>>>>>>>> "MultiVersionedKeyQuery"
> >>>>>> to sth
> >>>>>>>>>       else. We already had a long discussion about the name with
> >>>>>>>>> Matthias. I am
> >>>>>>>>>       open to renaming it to something else, but do you have any
> >>> ideas?
> >>>>>>>>>       3. Matthias suggested having a method with two input
> >>>>>>>>> parameters
> >>>>>> that
> >>>>>>>>>       enables the user to specify both time bounds in the same
> >>> method.
> >>>>>>>>> Isn't it
> >>>>>>>>>       introducing redundancy? It is somehow disrespectful to
> >>>>>>>>> the idea
> >>>>>> of
> >>>>>>>>> having
> >>>>>>>>>       composable methods.
> >>>>>>>>>       4. Bruno suggested renaming the methods "asOf" and "from" to
> >>>>>>>>> "asOfTime"
> >>>>>>>>>       and "fromTime". If I do that, then it is not consistent with
> >>>>>> KIP-960.
> >>>>>>>>>       Moreover, the input parameter is clearly a timestamp, which
> >>>>>> explains
> >>>>>>>>>       enough. What do you think about that?
> >>>>>>>>>       5. I was asked to add more examples to the example
> >>>>>>>>> section. My
> >>>>>>>>> question
> >>>>>>>>>       is, what is the main purpose of that? If I know it clearly,
> >>> then
> >>>>>> I
> >>>>>>>>> can add
> >>>>>>>>>       what you mean.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Cheers,
> >>>>>>>>> Alieh
> >>>>>>>>>
> >>>>>>>>> On Tue, Oct 10, 2023 at 1:13 AM Matthias J. Sax <mj...@apache.org>
> >>>>>> wrote:
> >>>>>>>>>
> >>>>>>>>>> Bruno and I had some background conversation about the `get`
> >>>>>>>>>> prefix
> >>>>>>>>>> question including a few other committers.
> >>>>>>>>>>
> >>>>>>>>>> The official policy was never changed, and we should not add the
> >>>>>>>>>> `get`-prefix. It's a slip on our side in previous KIPs to add the
> >>>>>>>>>> `get`-prefix and we should actually clean it up doing a follow up
> >>>>>> KIP.
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> -Matthias
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> On 10/5/23 5:26 AM, Bruno Cadonna wrote:
> >>>>>>>>>>> Hi Matthias,
> >>>>>>>>>>>
> >>>>>>>>>>> Given all the IQv2 KIPs that use getX and given recent PRs
> >>>>>> (internal
> >>>>>>>>>>> interfaces mainly) that got merged, I was under the impression
> >>>>>> that we
> >>>>>>>>>>> moved away from the strict no-getX policy.
> >>>>>>>>>>>
> >>>>>>>>>>> I do not think it was an accident using getX in the IQv2 KIPs
> >>> since
> >>>>>>>>>>> somebody would have brought it up, otherwise.
> >>>>>>>>>>>
> >>>>>>>>>>> I am fine with both types of getters.
> >>>>>>>>>>>
> >>>>>>>>>>> If we think, we need to discuss this in a broader context, let's
> >>>>>>>>>>> start a
> >>>>>>>>>>> separate thread.
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>> Best,
> >>>>>>>>>>> Bruno
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>> On 10/5/23 7:44 AM, Matthias J. Sax wrote:
> >>>>>>>>>>>> I agree to (almost) everything what Bruno said.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>> In general, we tend to move away from using getters without
> >>>>>> "get",
> >>>>>>>>>>>>> recently. So I would keep the "get".
> >>>>>>>>>>>>
> >>>>>>>>>>>> This is new to me? Can you elaborate on this point? Why do you
> >>>>>> think
> >>>>>>>>>>>> that's the case?
> >>>>>>>>>>>>
> >>>>>>>>>>>> I actually did realize (after Walker mentioned it) that
> >>>>>>>>>>>> existing
> >>>>>> query
> >>>>>>>>>>>> types use `get` prefix, but to me it seems that it was by
> >>>>>> accident and
> >>>>>>>>>>>> we should consider correcting it? Thus, I would actually prefer
> >>>>>> to not
> >>>>>>>>>>>> add the `get` prefix for new methods query types.
> >>>>>>>>>>>>
> >>>>>>>>>>>> IMHO, we should do a follow up KIP to deprecate all methods
> >>>>>>>>>>>> with
> >>>>>> `get`
> >>>>>>>>>>>> prefix and replace them with new ones without `get` -- it's of
> >>>>>> course
> >>>>>>>>>>>> always kinda "unnecessary" noise, but if we don't do it, we
> >>>>>>>>>>>> might
> >>>>>> get
> >>>>>>>>>>>> into more and more inconsistent naming what would result in a
> >>>>>> "bad"
> >>>>>>>>>>>> API.
> >>>>>>>>>>>>
> >>>>>>>>>>>> If we indeed want to change the convention and use the `get`
> >>>>>> prefix, I
> >>>>>>>>>>>> would strongly advocate to bit the bullet and do KIP to
> >>>>>> pro-actively
> >>>>>>>>>>>> add the `get` "everywhere" it's missing... But overall, it
> >>>>>>>>>>>> seems
> >>>>>> to be
> >>>>>>>>>>>> a much broader decision, and we should get buy in from many
> >>>>>> committers
> >>>>>>>>>>>> about it -- as long as there is no broad consensus to add `get`
> >>>>>>>>>>>> everywhere, I would strongly prefer not to diverge from the
> >>>>>> current
> >>>>>>>>>>>> agreement to omit `get`.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> -Matthias
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> On 10/4/23 2:36 AM, Bruno Cadonna wrote:
> >>>>>>>>>>>>> Hi,
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Regarding tombstones:
> >>>>>>>>>>>>> As far as I understand, we need to add either a validTo
> >>>>>>>>>>>>> field to
> >>>>>>>>>>>>> VersionedRecord or we need to return tombstones, otherwise the
> >>>>>> result
> >>>>>>>>>>>>> is not complete, because users could never know a record was
> >>>>>> deleted
> >>>>>>>>>>>>> at some point before the second non-null value was put.
> >>>>>>>>>>>>> I like more adding the validTo field since it makes the result
> >>>>>> more
> >>>>>>>>>>>>> concise and easier interpretable.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Extending on Victoria's example, with the following puts
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> put(k, v1, time=0)
> >>>>>>>>>>>>> put(k, null, time=5)
> >>>>>>>>>>>>> put(k, null, time=10)
> >>>>>>>>>>>>> put(k, null, time=15)
> >>>>>>>>>>>>> put(k, v2, time=20)
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> the result with tombstones would be
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> value, timestamp
> >>>>>>>>>>>>> (v1, 0)
> >>>>>>>>>>>>> (null, 5)
> >>>>>>>>>>>>> (null, 10)
> >>>>>>>>>>>>> (null, 15)
> >>>>>>>>>>>>> (v2, 20)
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> instead of
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> value, timestamp, validTo
> >>>>>>>>>>>>> (v1, 0, 5)
> >>>>>>>>>>>>> (v2, 20, null)
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> The benefit of conciseness would already apply to one single
> >>>>>>>>>>>>> tombstone.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> On the other hand, why would somebody write consecutive
> >>>>>> tombstones
> >>>>>>>>>>>>> into a versioned state store? I guess if somebody does that on
> >>>>>>>>>>>>> purpose, then there should be a way to retrieve each of those
> >>>>>>>>>>>>> tombstones, right?
> >>>>>>>>>>>>> So maybe we need both -- validTo field and the option to
> >>>>>>>>>>>>> return
> >>>>>>>>>>>>> tombstones. The latter might be moved to a future KIP in
> >>>>>>>>>>>>> case we
> >>>>>> see
> >>>>>>>>>>>>> the need.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Regarding .within(fromTs, toTs):
> >>>>>>>>>>>>> I would keep it simple with .from() and .asOfTimestamp() (or
> >>>>>>>>>>>>> .until()). If we go with .within(), I would opt for
> >>>>>>>>>>>>> .withinTimeRange(fromTs, toTs), because the query becomes more
> >>>>>>>>>> readable:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> MultiVersionedKeyQuery
> >>>>>>>>>>>>>       .withKey(1)
> >>>>>>>>>>>>>       .withinTimeRange(Instant.parse(2023-08-03T10:37:30.00Z),
> >>>>>>>>>>>>> Instant.parse(2023-08-04T10:37:30.00Z))
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> If we stay with .from() and .until(), we should consider
> >>>>>> .fromTime()
> >>>>>>>>>>>>> and .untilTime() (or .toTime()):
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> MultiVersionedKeyQuery
> >>>>>>>>>>>>>      .withKey(1)
> >>>>>>>>>>>>>      .fromTime(Instant.parse(2023-08-03T10:37:30.00Z))
> >>>>>>>>>>>>>      .untilTime(Instant.parse(2023-08-04T10:37:30.00Z))
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Regarding asOf vs. until:
> >>>>>>>>>>>>> I think asOf() is more used in point in time queries as Walker
> >>>>>>>>>>>>> mentioned where this KIP specifies a time range. IMO asOf()
> >>>>>>>>>>>>> fits
> >>>>>> very
> >>>>>>>>>>>>> well with KIP-960 where one version is queried, but here I
> >>>>>>>>>>>>> think
> >>>>>>>>>>>>> .until() fits better. That might just be a matter of taste and
> >>>>>> in the
> >>>>>>>>>>>>> end I am fine with both as long as it is well documented.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Regarding getters without "get":
> >>>>>>>>>>>>> In the other IQv2 classes we used getters with "get". In
> >>>>>> general, we
> >>>>>>>>>>>>> tend to move away from using getters without "get",
> >>>>>>>>>>>>> recently. So
> >>>>>> I
> >>>>>>>>>>>>> would keep the "get".
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Best,
> >>>>>>>>>>>>> Bruno
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> On 10/3/23 7:49 PM, Walker Carlson wrote:
> >>>>>>>>>>>>>> Hey Alieh thanks for the KIP,
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Weighing in on the AsOf vs Until debate I think either is
> >>>>>>>>>>>>>> fine
> >>>>>>>>>>>>>> from a
> >>>>>>>>>>>>>> natural language perspective. Personally AsOf makes more
> >>>>>>>>>>>>>> sense
> >>>>>> to me
> >>>>>>>>>>>>>> where
> >>>>>>>>>>>>>> until gives me the idea that the query is making a change.
> >>>>>>>>>>>>>> It's
> >>>>>>>>>>>>>> totally a
> >>>>>>>>>>>>>> connotative difference and not that important. I think as
> >>>>>>>>>>>>>> of is
> >>>>>>>>>>>>>> pretty
> >>>>>>>>>>>>>> frequently used in point of time queries.
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Also for these methods it makes sense to drop the "get" We
> >>> don't
> >>>>>>>>>>>>>> normally use that in getters
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>        * The key that was specified for this query.
> >>>>>>>>>>>>>>        */
> >>>>>>>>>>>>>>       public K getKey();
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>       /**
> >>>>>>>>>>>>>>        * The starting time point of the query, if specified
> >>>>>>>>>>>>>>        */
> >>>>>>>>>>>>>>       public Optional<Instant> getFromTimestamp();
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>       /**
> >>>>>>>>>>>>>>        * The ending time point of the query, if specified
> >>>>>>>>>>>>>>        */
> >>>>>>>>>>>>>>       public Optional<Instant> getAsOfTimestamp();
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Other than that I didn't have too much to add. Overall I like
> >>>>>> the
> >>>>>>>>>>>>>> direction
> >>>>>>>>>>>>>> of the KIP and think the funcatinlyt is all there!
> >>>>>>>>>>>>>> best,
> >>>>>>>>>>>>>> Walker
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> On Mon, Oct 2, 2023 at 10:46 PM Matthias J. Sax <
> >>>>>> mj...@apache.org>
> >>>>>>>>>>>>>> wrote:
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Thanks for the updated KIP. Overall I like it.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Victoria raises a very good point, and I personally tend to
> >>>>>>>>>>>>>>> prefer (I
> >>>>>>>>>>>>>>> believe so does Victoria, but it's not totally clear from
> >>>>>>>>>>>>>>> her
> >>>>>>>>>>>>>>> email) if
> >>>>>>>>>>>>>>> a range query would not return any tombstones, ie, only two
> >>>>>> records
> >>>>>>>>>> in
> >>>>>>>>>>>>>>> Victoria's example. Thus, it seems best to include a
> >>>>>>>>>>>>>>> `validTo`
> >>>>>>>>>>>>>>> ts-field
> >>>>>>>>>>>>>>> to `VersionedRecord` -- otherwise, the retrieved result
> >>>>>>>>>>>>>>> cannot
> >>>>>> be
> >>>>>>>>>>>>>>> interpreted correctly.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Not sure what others think about it.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> I would also be open to actually add a `includeDeletes()`
> >>>>>>>>>>>>>>> (or
> >>>>>>>>>>>>>>> `includeTombstones()`) method/flag (disabled by default) to
> >>>>>> allow
> >>>>>>>>>>>>>>> users
> >>>>>>>>>>>>>>> to get all tombstone: this would only be helpful if there
> >>>>>>>>>>>>>>> are
> >>>>>> two
> >>>>>>>>>>>>>>> consecutive tombstone though (if I got it right), so not
> >>>>>>>>>>>>>>> sure
> >>>>>> if we
> >>>>>>>>>>>>>>> want
> >>>>>>>>>>>>>>> to add it or not -- it seems also possible to add it
> >>>>>>>>>>>>>>> later if
> >>>>>> there
> >>>>>>>>>> is
> >>>>>>>>>>>>>>> user demand for it, so it might be a premature addition as
> >>> this
> >>>>>>>>>> point?
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Nit:
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> the public interface ValueIterator is used
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> "is used" -> "is added" (otherwise it sounds like as if
> >>>>>>>>>>>>>>> `ValueIterator`
> >>>>>>>>>>>>>>> exist already)
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Should we also add a `.within(fromTs, toTs)` (or maybe some
> >>>>>> better
> >>>>>>>>>>>>>>> name?) to allow specifying both bounds at once? The existing
> >>>>>>>>>>>>>>> `RangeQuery` does the same for specifying the key-range, so
> >>>>>>>>>>>>>>> might be
> >>>>>>>>>>>>>>> good to add for time-range too?
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> -Matthias
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> On 9/6/23 5:01 AM, Bruno Cadonna wrote:
> >>>>>>>>>>>>>>>> In my last e-mail I missed to finish a sentence.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> "I think from a KIP"
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> should be
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> "I think the KIP looks good!"
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> On 9/6/23 1:59 PM, Bruno Cadonna wrote:
> >>>>>>>>>>>>>>>>> Hi Alieh,
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Thanks for the KIP!
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> I think from a KIP
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 1.
> >>>>>>>>>>>>>>>>> I propose to throw an IllegalArgumentException or an
> >>>>>>>>>>>>>>>>> IllegalStateException for meaningless combinations. In any
> >>>>>> case,
> >>>>>>>>>> the
> >>>>>>>>>>>>>>>>> KIP should specify what exception is thrown.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 2.
> >>>>>>>>>>>>>>>>> Why does not specifying a range return the latest
> >>>>>>>>>>>>>>>>> version? I
> >>>>>>>>>>>>>>>>> would
> >>>>>>>>>>>>>>>>> expect that it returns all versions since an empty
> >>>>>>>>>>>>>>>>> lower or
> >>>>>> upper
> >>>>>>>>>>>>>>>>> limit is interpreted as no limit.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 3.
> >>>>>>>>>>>>>>>>> I second Matthias comment about replacing "asOf" with
> >>>>>> "until" or
> >>>>>>>>>>>>>>>>> "to".
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 4.
> >>>>>>>>>>>>>>>>> Do we need "allVersions()"? As I said above I would return
> >>>>>> all
> >>>>>>>>>>>>>>>>> versions if no limits are specified. I think if we get rid
> >>> of
> >>>>>>>>>>>>>>>>> allVersions() there might not be any meaningless
> >>> combinations
> >>>>>>>>>>>>>>>>> anymore.
> >>>>>>>>>>>>>>>>> If a user applies twice the same limit like for example
> >>>>>>>>>>>>>>>>> MultiVersionedKeyQuery.with(key).from(t1).from(t2) the
> >>>>>>>>>>>>>>>>> last
> >>>>>> one
> >>>>>>>>>>>>>>>>> wins.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 5.
> >>>>>>>>>>>>>>>>> Could you add some more examples with time ranges to the
> >>>>>> example
> >>>>>>>>>>>>>>> section?
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 6.
> >>>>>>>>>>>>>>>>> The KIP misses the test plan section.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 7.
> >>>>>>>>>>>>>>>>> I propose to rename the class to "MultiVersionKeyQuery"
> >>>>>> since we
> >>>>>>>>>> are
> >>>>>>>>>>>>>>>>> querying multiple versions of the same key.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> 8.
> >>>>>>>>>>>>>>>>> Could you also add withAscendingTimestamps()? IMO it gives
> >>>>>> users
> >>>>>>>>>> the
> >>>>>>>>>>>>>>>>> possibility to make their code more readable instead of
> >>>>>>>>>>>>>>>>> only
> >>>>>>>>>> relying
> >>>>>>>>>>>>>>>>> on the default.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Best,
> >>>>>>>>>>>>>>>>> Bruno
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> On 8/17/23 4:13 AM, Matthias J. Sax wrote:
> >>>>>>>>>>>>>>>>>> Thanks for splitting this part into a separate KIP!
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> For `withKey()` we should be explicit that `null` is not
> >>>>>>>>>>>>>>>>>> allowed.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> (Looking into existing `KeyQuery` it seems the JavaDocs
> >>>>>> don't
> >>>>>>>>>> cover
> >>>>>>>>>>>>>>>>>> this either -- would you like to do a tiny cleanup PR for
> >>>>>>>>>>>>>>>>>> this, or
> >>>>>>>>>>>>>>>>>> fix on-the-side in one of your PRs?)
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> The key query returns all the records that are valid in
> >>> the
> >>>>>>>>>>>>>>>>>>> time
> >>>>>>>>>>>>>>>>>>> range starting from the timestamp {@code fromTimestamp}.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> In the JavaDocs you use the phrase `are valid` -- I think
> >>> we
> >>>>>>>>>>>>>>>>>> need to
> >>>>>>>>>>>>>>>>>> explain what "valid" means? It might even be worth to add
> >>>>>> some
> >>>>>>>>>>>>>>>>>> examples. It's annoying, but being precise if kinda
> >>>>>> important.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> With regard to KIP-962, should we allow `null` for time
> >>>>>> bounds ?
> >>>>>>>>>>>>>>>>>> The
> >>>>>>>>>>>>>>>>>> JavaDocs should also be explicit if `null` is allowed or
> >>>>>> not and
> >>>>>>>>>>>>>>>>>> what
> >>>>>>>>>>>>>>>>>> the semantics are if allowed.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> You are using `asOf()` however, because we are doing
> >>>>>> time-range
> >>>>>>>>>>>>>>>>>> queries, to me using `until()` to describe the upper
> >>>>>>>>>>>>>>>>>> bound
> >>>>>> would
> >>>>>>>>>>>>>>>>>> sound better (I am not a native speaker though, so
> >>>>>>>>>>>>>>>>>> maybe I
> >>>>>> am
> >>>>>>>>>> off?)
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> The key query returns all the records that have
> >>>>>>>>>>>>>>>>>>> timestamp
> >>>>>> <=
> >>>>>>>>>>>>>>>>>>> {@code
> >>>>>>>>>>>>>>>>>>> asOfTimestamp}.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> This is only correct if not lower-bound is set, right?
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> In your reply to KIP-960 you mentioned:
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> the meaningless combinations are prevented by throwing
> >>>>>>>>>> exceptions.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> We should add corresponding JavaDocs like:
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>         @throws IllegalArgumentException if {@code
> >>>>>>>>>>>>>>>>>> fromTimestamp} is
> >>>>>>>>>>>>>>>>>> equal or
> >>>>>>>>>>>>>>>>>>                                          larger than
> >>>>>>>>>>>>>>>>>> {@code
> >>>>>>>>>>>>>>>>>> untilTimestamp}
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> Or something similar.
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> With regard to KIP-960: if we need to introduce a
> >>>>>>>>>>>>>>>>>> `VersionedKeyQuery`
> >>>>>>>>>>>>>>>>>> class for single-key-single-ts lookup, would we need to
> >>> find
> >>>>>>>>>>>>>>>>>> a new
> >>>>>>>>>>>>>>>>>> name for the query class of this KIP, given that the
> >>>>>>>>>>>>>>>>>> return
> >>>>>> type
> >>>>>>>>>> is
> >>>>>>>>>>>>>>>>>> different?
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> -Matthias
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> On 8/16/23 10:57 AM, Alieh Saeedi wrote:
> >>>>>>>>>>>>>>>>>>> Hi all,
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> I splitted KIP-960
> >>>>>>>>>>>>>>>>>>> <
> >>>>>>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>
> >>> https://cwiki.apache.org/confluence/display/KAFKA/KIP-960%3A+Support+single-key_single-timestamp+interactive+queries+%28IQv2%29+for+versioned+state+stores
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> into three separate KIPs. Therefore, please continue
> >>>>>>>>>>>>>>>>>>> discussions
> >>>>>>>>>>>>>>>>>>> about single-key, multi-timestamp interactive queries
> >>>>>> here. You
> >>>>>>>>>>>>>>>>>>> can
> >>>>>>>>>>>>>>>>>>> see all
> >>>>>>>>>>>>>>>>>>> the addressed reviews on the following page. Thanks in
> >>>>>> advance.
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> KIP-968: Support single-key_multi-timestamp interactive
> >>>>>> queries
> >>>>>>>>>>>>>>>>>>> (IQv2) for
> >>>>>>>>>>>>>>>>>>> versioned state stores
> >>>>>>>>>>>>>>>>>>> <
> >>>>>>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>
> >>> https://cwiki.apache.org/confluence/display/KAFKA/KIP-968%3A+Support+single-key_multi-timestamp+interactive+queries+%28IQv2%29+for+versioned+state+stores
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> I look forward to your feedback!
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> Cheers,
> >>>>>>>>>>>>>>>>>>> Alieh
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>

Reply via email to