@ -474,7 +474,7 @@ void StressTest::PreloadDbAndReopenAsReadOnly(int64_t number_of_keys,
std : : string ts_str ;
std : : string ts_str ;
Slice ts ;
Slice ts ;
if ( FLAGS_user_timestamp_size > 0 ) {
if ( FLAGS_user_timestamp_size > 0 ) {
ts_str = NowNanosStr ( ) ;
ts_str = Get NowNanos( ) ;
ts = ts_str ;
ts = ts_str ;
s = db_ - > Put ( write_opts , cfh , key , ts , v ) ;
s = db_ - > Put ( write_opts , cfh , key , ts , v ) ;
} else {
} else {
@ -856,10 +856,10 @@ void StressTest::OperateDb(ThreadState* thread) {
Slice read_ts ;
Slice read_ts ;
Slice write_ts ;
Slice write_ts ;
if ( ShouldAcquireMutexOnKey ( ) & & FLAGS_user_timestamp_size > 0 ) {
if ( ShouldAcquireMutexOnKey ( ) & & FLAGS_user_timestamp_size > 0 ) {
read_ts_str = GenerateTimestampForRead ( ) ;
read_ts_str = GetNowNanos ( ) ;
read_ts = read_ts_str ;
read_ts = read_ts_str ;
read_opts . timestamp = & read_ts ;
read_opts . timestamp = & read_ts ;
write_ts_str = NowNanosStr ( ) ;
write_ts_str = Get NowNanos( ) ;
write_ts = write_ts_str ;
write_ts = write_ts_str ;
}
}
@ -1004,6 +1004,11 @@ Status StressTest::TestIterate(ThreadState* thread,
ReadOptions readoptionscopy = read_opts ;
ReadOptions readoptionscopy = read_opts ;
readoptionscopy . snapshot = snapshot ;
readoptionscopy . snapshot = snapshot ;
std : : string read_ts_str ;
Slice read_ts_slice ;
MaybeUseOlderTimestampForRangeScan ( thread , read_ts_str , read_ts_slice ,
readoptionscopy ) ;
bool expect_total_order = false ;
bool expect_total_order = false ;
if ( thread - > rand . OneIn ( 16 ) ) {
if ( thread - > rand . OneIn ( 16 ) ) {
// When prefix extractor is used, it's useful to cover total order seek.
// When prefix extractor is used, it's useful to cover total order seek.
@ -1106,6 +1111,7 @@ Status StressTest::TestIterate(ThreadState* thread,
// `FLAGS_rate_limit_user_ops` to avoid slowing any validation.
// `FLAGS_rate_limit_user_ops` to avoid slowing any validation.
ReadOptions cmp_ro ;
ReadOptions cmp_ro ;
cmp_ro . timestamp = readoptionscopy . timestamp ;
cmp_ro . timestamp = readoptionscopy . timestamp ;
cmp_ro . iter_start_ts = readoptionscopy . iter_start_ts ;
cmp_ro . snapshot = snapshot ;
cmp_ro . snapshot = snapshot ;
cmp_ro . total_order_seek = true ;
cmp_ro . total_order_seek = true ;
ColumnFamilyHandle * cmp_cfh =
ColumnFamilyHandle * cmp_cfh =
@ -1216,6 +1222,14 @@ void StressTest::VerifyIterator(ThreadState* thread,
return ;
return ;
}
}
if ( ro . iter_start_ts ! = nullptr ) {
assert ( FLAGS_user_timestamp_size > 0 ) ;
// We currently do not verify iterator when dumping history of internal
// keys.
* diverged = true ;
return ;
}
if ( op = = kLastOpSeekToFirst & & ro . iterate_lower_bound ! = nullptr ) {
if ( op = = kLastOpSeekToFirst & & ro . iterate_lower_bound ! = nullptr ) {
// SeekToFirst() with lower bound is not well defined.
// SeekToFirst() with lower bound is not well defined.
* diverged = true ;
* diverged = true ;
@ -1558,7 +1572,7 @@ Status StressTest::TestBackupRestore(
std : : string ts_str ;
std : : string ts_str ;
Slice ts ;
Slice ts ;
if ( FLAGS_user_timestamp_size > 0 ) {
if ( FLAGS_user_timestamp_size > 0 ) {
ts_str = GenerateTimestampForRead ( ) ;
ts_str = GetNowNanos ( ) ;
ts = ts_str ;
ts = ts_str ;
read_opts . timestamp = & ts ;
read_opts . timestamp = & ts ;
}
}
@ -1749,7 +1763,7 @@ Status StressTest::TestCheckpoint(ThreadState* thread,
Slice ts ;
Slice ts ;
ReadOptions read_opts ;
ReadOptions read_opts ;
if ( FLAGS_user_timestamp_size > 0 ) {
if ( FLAGS_user_timestamp_size > 0 ) {
ts_str = GenerateTimestampForRead ( ) ;
ts_str = GetNowNanos ( ) ;
ts = ts_str ;
ts = ts_str ;
read_opts . timestamp = & ts ;
read_opts . timestamp = & ts ;
}
}
@ -1976,7 +1990,7 @@ void StressTest::TestAcquireSnapshot(ThreadState* thread,
std : : string ts_str ;
std : : string ts_str ;
Slice ts ;
Slice ts ;
if ( FLAGS_user_timestamp_size > 0 ) {
if ( FLAGS_user_timestamp_size > 0 ) {
ts_str = GenerateTimestampForRead ( ) ;
ts_str = GetNowNanos ( ) ;
ts = ts_str ;
ts = ts_str ;
ropt . timestamp = & ts ;
ropt . timestamp = & ts ;
}
}
@ -2129,7 +2143,7 @@ uint32_t StressTest::GetRangeHash(ThreadState* thread, const Snapshot* snapshot,
std : : string ts_str ;
std : : string ts_str ;
Slice ts ;
Slice ts ;
if ( FLAGS_user_timestamp_size > 0 ) {
if ( FLAGS_user_timestamp_size > 0 ) {
ts_str = GenerateTimestampForRead ( ) ;
ts_str = GetNowNanos ( ) ;
ts = ts_str ;
ts = ts_str ;
ro . timestamp = & ts ;
ro . timestamp = & ts ;
}
}
@ -2700,6 +2714,75 @@ void StressTest::Reopen(ThreadState* thread) {
}
}
}
}
void StressTest : : MaybeUseOlderTimestampForPointLookup ( ThreadState * thread ,
std : : string & ts_str ,
Slice & ts_slice ,
ReadOptions & read_opts ) {
if ( FLAGS_user_timestamp_size = = 0 ) {
return ;
}
assert ( thread ) ;
if ( ! thread - > rand . OneInOpt ( 3 ) ) {
return ;
}
const SharedState * const shared = thread - > shared ;
assert ( shared ) ;
const uint64_t start_ts = shared - > GetStartTimestamp ( ) ;
uint64_t now = db_stress_env - > NowNanos ( ) ;
assert ( now > start_ts ) ;
uint64_t time_diff = now - start_ts ;
uint64_t ts = start_ts + ( thread - > rand . Next64 ( ) % time_diff ) ;
ts_str . clear ( ) ;
PutFixed64 ( & ts_str , ts ) ;
ts_slice = ts_str ;
read_opts . timestamp = & ts_slice ;
}
void StressTest : : MaybeUseOlderTimestampForRangeScan ( ThreadState * thread ,
std : : string & ts_str ,
Slice & ts_slice ,
ReadOptions & read_opts ) {
if ( FLAGS_user_timestamp_size = = 0 ) {
return ;
}
assert ( thread ) ;
if ( ! thread - > rand . OneInOpt ( 3 ) ) {
return ;
}
const Slice * const saved_ts = read_opts . timestamp ;
assert ( saved_ts ! = nullptr ) ;
const SharedState * const shared = thread - > shared ;
assert ( shared ) ;
const uint64_t start_ts = shared - > GetStartTimestamp ( ) ;
uint64_t now = db_stress_env - > NowNanos ( ) ;
assert ( now > start_ts ) ;
uint64_t time_diff = now - start_ts ;
uint64_t ts = start_ts + ( thread - > rand . Next64 ( ) % time_diff ) ;
ts_str . clear ( ) ;
PutFixed64 ( & ts_str , ts ) ;
ts_slice = ts_str ;
read_opts . timestamp = & ts_slice ;
if ( ! thread - > rand . OneInOpt ( 3 ) ) {
return ;
}
ts_str . clear ( ) ;
PutFixed64 ( & ts_str , start_ts ) ;
ts_slice = ts_str ;
read_opts . iter_start_ts = & ts_slice ;
read_opts . timestamp = saved_ts ;
}
void CheckAndSetOptionsForUserTimestamp ( Options & options ) {
void CheckAndSetOptionsForUserTimestamp ( Options & options ) {
assert ( FLAGS_user_timestamp_size > 0 ) ;
assert ( FLAGS_user_timestamp_size > 0 ) ;
const Comparator * const cmp = test : : BytewiseComparatorWithU64TsWrapper ( ) ;
const Comparator * const cmp = test : : BytewiseComparatorWithU64TsWrapper ( ) ;