@@ -1646,84 +1646,198 @@ TEST_F(DBBasicTestWithTimestamp, GetWithRowCache) {
1646
1646
1647
1647
const Snapshot* snap_with_nothing = db_->GetSnapshot ();
1648
1648
ASSERT_OK (db_->Put (write_opts, " foo" , ts_early, " bar" ));
1649
- const Snapshot* snap_with_foo = db_->GetSnapshot ();
1649
+ ASSERT_OK (db_->Put (write_opts, " foo2" , ts_early, " bar2" ));
1650
+ ASSERT_OK (db_->Put (write_opts, " foo3" , ts_early, " bar3" ));
1650
1651
1651
- // Ensure file has sequence number greater than snapshot_with_foo
1652
- for (int i = 0 ; i < 10 ; i++) {
1653
- std::string numStr = std::to_string (i);
1654
- ASSERT_OK (db_->Put (write_opts, numStr, ts_later, numStr));
1655
- }
1652
+ const Snapshot* snap_with_foo = db_->GetSnapshot ();
1656
1653
ASSERT_OK (Flush ());
1657
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 0 );
1658
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 0 );
1659
1654
1660
1655
ReadOptions read_opts;
1661
1656
read_opts.timestamp = &ts_later_slice;
1662
1657
1663
1658
std::string read_value;
1664
1659
std::string read_ts;
1665
- Status s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1666
- ASSERT_OK (s);
1667
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 0 );
1668
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 1 );
1669
- ASSERT_EQ (read_ts, ts_early);
1660
+ Status s;
1670
1661
1671
- s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1672
- ASSERT_OK (s);
1673
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 1 );
1674
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 1 );
1675
- // Row cache is not storing the ts when record is inserted/updated.
1676
- // To be fixed after enabling ROW_CACHE with timestamp.
1677
- // ASSERT_EQ(read_ts, ts_early);
1662
+ int expected_hit_count = 0 ;
1663
+ int expected_miss_count = 0 ;
1664
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1665
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), expected_miss_count);
1666
+
1667
+ {
1668
+ read_opts.timestamp = nullptr ;
1669
+ s = db_->Get (read_opts, " foo" , &read_value);
1670
+ ASSERT_NOK (s);
1671
+ ASSERT_TRUE (s.IsInvalidArgument ());
1672
+ }
1673
+
1674
+ // Mix use of Get
1675
+ {
1676
+ read_opts.timestamp = &ts_later_slice;
1677
+
1678
+ // Use Get without ts first, expect cache entry to store the correct ts
1679
+ s = db_->Get (read_opts, " foo2" , &read_value);
1680
+ ASSERT_OK (s);
1681
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1682
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1683
+ ++expected_miss_count);
1684
+ ASSERT_EQ (read_value, " bar2" );
1685
+
1686
+ s = db_->Get (read_opts, " foo2" , &read_value, &read_ts);
1687
+ ASSERT_OK (s);
1688
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), ++expected_hit_count);
1689
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), expected_miss_count);
1690
+ ASSERT_EQ (read_ts, ts_early);
1691
+ ASSERT_EQ (read_value, " bar2" );
1692
+
1693
+ // Use Get with ts first, expect the Get without ts can get correct record
1694
+ s = db_->Get (read_opts, " foo3" , &read_value, &read_ts);
1695
+ ASSERT_OK (s);
1696
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1697
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1698
+ ++expected_miss_count);
1699
+ ASSERT_EQ (read_ts, ts_early);
1700
+ ASSERT_EQ (read_value, " bar3" );
1701
+
1702
+ s = db_->Get (read_opts, " foo3" , &read_value);
1703
+ ASSERT_OK (s);
1704
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), ++expected_hit_count);
1705
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), expected_miss_count);
1706
+ ASSERT_EQ (read_value, " bar3" );
1707
+ }
1708
+
1709
+ {
1710
+ // Test with consecutive calls of Get with ts.
1711
+ s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1712
+ ASSERT_OK (s);
1713
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1714
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1715
+ ++expected_miss_count);
1716
+ ASSERT_EQ (read_ts, ts_early);
1717
+ ASSERT_EQ (read_value, " bar" );
1718
+
1719
+ // Test repeated get on cache entry
1720
+ for (int i = 0 ; i < 3 ; i++) {
1721
+ s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1722
+ ASSERT_OK (s);
1723
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT),
1724
+ ++expected_hit_count);
1725
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1726
+ expected_miss_count);
1727
+ ASSERT_EQ (read_ts, ts_early);
1728
+ ASSERT_EQ (read_value, " bar" );
1729
+ }
1730
+ }
1678
1731
1679
1732
{
1680
1733
std::string ts_nothing = Timestamp (0 , 0 );
1681
1734
Slice ts_nothing_slice = ts_nothing;
1682
1735
read_opts.timestamp = &ts_nothing_slice;
1683
1736
s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1684
1737
ASSERT_TRUE (s.IsNotFound ());
1685
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 1 );
1686
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 2 );
1687
-
1688
- read_opts.timestamp = &ts_later_slice;
1689
- s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1690
- ASSERT_OK (s);
1691
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 2 );
1692
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 2 );
1738
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1739
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1740
+ ++expected_miss_count);
1693
1741
}
1694
1742
1695
1743
{
1696
1744
read_opts.snapshot = snap_with_foo;
1697
-
1745
+ read_opts. timestamp = &ts_later_slice;
1698
1746
s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1699
1747
ASSERT_OK (s);
1700
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 2 );
1701
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 3 );
1748
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1749
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1750
+ ++expected_miss_count);
1751
+ ASSERT_EQ (read_ts, ts_early);
1752
+ ASSERT_EQ (read_value, " bar" );
1702
1753
1703
1754
s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1704
1755
ASSERT_OK (s);
1705
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 3 );
1706
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 3 );
1756
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), ++expected_hit_count);
1757
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), expected_miss_count);
1758
+ ASSERT_EQ (read_ts, ts_early);
1759
+ ASSERT_EQ (read_value, " bar" );
1707
1760
}
1708
1761
1709
1762
{
1710
1763
read_opts.snapshot = snap_with_nothing;
1711
1764
s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1712
1765
ASSERT_TRUE (s.IsNotFound ());
1713
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 3 );
1714
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 4 );
1766
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1767
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1768
+ ++expected_miss_count);
1715
1769
1716
1770
s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1717
1771
ASSERT_TRUE (s.IsNotFound ());
1718
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 3 );
1719
- ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 5 );
1772
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), expected_hit_count);
1773
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS),
1774
+ ++expected_miss_count);
1720
1775
}
1721
1776
1722
1777
db_->ReleaseSnapshot (snap_with_nothing);
1723
1778
db_->ReleaseSnapshot (snap_with_foo);
1724
1779
Close ();
1725
1780
}
1726
1781
1782
+ TEST_F (DBBasicTestWithTimestamp, GetWithRowCacheMultiSST) {
1783
+ BlockBasedTableOptions table_options;
1784
+ table_options.block_size = 1 ;
1785
+ Options options = CurrentOptions ();
1786
+ options.env = env_;
1787
+ options.create_if_missing = true ;
1788
+ options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics ();
1789
+ LRUCacheOptions cache_options;
1790
+ cache_options.capacity = 8192 ;
1791
+ options.row_cache = cache_options.MakeSharedRowCache ();
1792
+
1793
+ const size_t kTimestampSize = Timestamp (0 , 0 ).size ();
1794
+ TestComparator test_cmp (kTimestampSize );
1795
+ options.comparator = &test_cmp;
1796
+ options.table_factory .reset (NewBlockBasedTableFactory (table_options));
1797
+ options.merge_operator = MergeOperators::CreateStringAppendTESTOperator ();
1798
+ options.disable_auto_compactions = true ;
1799
+
1800
+ DestroyAndReopen (options);
1801
+
1802
+ std::string ts_early = Timestamp (1 , 0 );
1803
+ std::string ts_later = Timestamp (10 , 0 );
1804
+ Slice ts_later_slice = ts_later;
1805
+
1806
+ ASSERT_OK (db_->Put (WriteOptions (), " foo" , ts_early, " v1" ));
1807
+ ASSERT_OK (Flush ());
1808
+
1809
+ ColumnFamilyHandle* default_cf = db_->DefaultColumnFamily ();
1810
+ ASSERT_OK (
1811
+ db_->Merge (WriteOptions (), default_cf, " foo" , Timestamp (2 , 0 ), " v2" ));
1812
+ ASSERT_OK (
1813
+ db_->Merge (WriteOptions (), default_cf, " foo" , Timestamp (3 , 0 ), " v3" ));
1814
+ ASSERT_OK (Flush ());
1815
+
1816
+ ReadOptions read_opts;
1817
+ read_opts.timestamp = &ts_later_slice;
1818
+
1819
+ std::string read_value;
1820
+ std::string read_ts;
1821
+ Status s;
1822
+
1823
+ {
1824
+ // Since there are two SST files, will trigger the table lookup twice.
1825
+ s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1826
+ ASSERT_OK (s);
1827
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 0 );
1828
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 2 );
1829
+ ASSERT_EQ (read_ts, Timestamp (3 , 0 ));
1830
+ ASSERT_EQ (read_value, " v1,v2,v3" );
1831
+
1832
+ s = db_->Get (read_opts, " foo" , &read_value, &read_ts);
1833
+ ASSERT_OK (s);
1834
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_HIT), 2 );
1835
+ ASSERT_EQ (TestGetTickerCount (options, ROW_CACHE_MISS), 2 );
1836
+ ASSERT_EQ (read_ts, Timestamp (3 , 0 ));
1837
+ ASSERT_EQ (read_value, " v1,v2,v3" );
1838
+ }
1839
+ }
1840
+
1727
1841
TEST_P (DBBasicTestWithTimestampTableOptions, MultiGetPrefixFilter) {
1728
1842
Options options = CurrentOptions ();
1729
1843
options.env = env_;
0 commit comments