aliehsaeedii commented on code in PR #14626:
URL: https://github.com/apache/kafka/pull/14626#discussion_r1416196786


##########
streams/src/test/java/org/apache/kafka/streams/state/internals/RocksDBVersionedStoreTest.java:
##########
@@ -471,15 +475,195 @@ public void shouldDistinguishEmptyAndNull() {
         verifyGetNullFromStore("k");
         verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL + 30);
         verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL + 15);
-        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL + 6, "", 
SEGMENT_INTERVAL + 5);
+        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL + 6, "", 
SEGMENT_INTERVAL + 5, SEGMENT_INTERVAL + 10);
         verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL + 2);
         verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL);
         verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL - 1);
-        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 5, "", 
SEGMENT_INTERVAL - 5);
-        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 6, "", 
SEGMENT_INTERVAL - 6);
+        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 5, "", 
SEGMENT_INTERVAL - 5, SEGMENT_INTERVAL - 1);
+        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 6, "", 
SEGMENT_INTERVAL - 6, SEGMENT_INTERVAL - 5);
         verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL - 8);
     }
 
+    @Test
+    public void shouldGetRecordVersionsFromOlderSegments() {
+        // use a different key to create three different segments
+        putToStore("ko", null, SEGMENT_INTERVAL - 10, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("ko", null, 2 * SEGMENT_INTERVAL - 10, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("ko", null, 3 * SEGMENT_INTERVAL - 10, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+
+        // return null after visiting all segments (the key does not exist.)
+        verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL - 20, 
SEGMENT_INTERVAL);
+
+        // insert data to create non-empty (first) segment
+        putToStore("k", "v1", SEGMENT_INTERVAL - 30, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("k", "v2", SEGMENT_INTERVAL - 25, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("k", null, SEGMENT_INTERVAL - 20, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("k", null, SEGMENT_INTERVAL - 15, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("k", "v3", SEGMENT_INTERVAL - 10, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+        putToStore("k", "v4", SEGMENT_INTERVAL - 5, 
PUT_RETURN_CODE_VALID_TO_UNDEFINED);
+
+
+        // return null for the query with a time range prior to inserting 
values
+        verifyTimestampedGetNullFromStore("k", SEGMENT_INTERVAL - 40, 
SEGMENT_INTERVAL - 35);
+
+        // return values for the query with query time range in which values 
are still valid and there are multiple tombstones
+        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 30, 
SEGMENT_INTERVAL - 5, ResultOrder.ANY,
+                                            Arrays.asList("v4", "v3", "v2", 
"v1"),
+                                            Arrays.asList(SEGMENT_INTERVAL - 
5, SEGMENT_INTERVAL - 10, SEGMENT_INTERVAL - 25, SEGMENT_INTERVAL - 30),
+                                            
Arrays.asList(PUT_RETURN_CODE_VALID_TO_UNDEFINED, SEGMENT_INTERVAL - 5, 
SEGMENT_INTERVAL - 20, SEGMENT_INTERVAL - 25));
+
+        // return values for the query with time range (MIN, MAX)
+        verifyTimestampedGetValueFromStore("k", Long.MIN_VALUE, 
Long.MAX_VALUE, ResultOrder.ANY,
+                                           Arrays.asList("v4", "v3", "v2", 
"v1"),
+                                           Arrays.asList(SEGMENT_INTERVAL - 5, 
SEGMENT_INTERVAL - 10, SEGMENT_INTERVAL - 25, SEGMENT_INTERVAL - 30),
+                                           
Arrays.asList(PUT_RETURN_CODE_VALID_TO_UNDEFINED, SEGMENT_INTERVAL - 5, 
SEGMENT_INTERVAL - 20, SEGMENT_INTERVAL - 25));
+
+        // return the latest record (retrieve only from the latestValueStore)
+        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 4, 
SEGMENT_INTERVAL, ResultOrder.ANY,
+                                            Collections.singletonList("v4"),
+                                            
Collections.singletonList(SEGMENT_INTERVAL - 5),
+                                            
Collections.singletonList(PUT_RETURN_CODE_VALID_TO_UNDEFINED));
+
+        // return two values for the query with time fromTimeStamp = 
toTimestamp
+        verifyTimestampedGetValueFromStore("k", SEGMENT_INTERVAL - 5, 
SEGMENT_INTERVAL - 5, ResultOrder.ANY,

Review Comment:
   > Should this not return only one value, `v4`, because `v3` is not valid any 
longer? It's upper bound is exclusive, and `[-10,-5)` does not intersect with 
search interval `[-5,-5]` (a `[-5,-5]` range query is basically a point in time 
query and should return the same as `KeyQuery#asOf(-5)`), right?
   
   Sorry. Good that we have javadocs otherwise we had to discuss it again! `The 
key query in fact returns all the records that have NOT become tombstone at or 
after {@code fromTime}.` I missed the word `at`:(



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscr...@kafka.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to