@@ -2049,6 +2049,128 @@ TEST(sqlite_cache_setting_default) {
20492049 sqlite3_close (db );
20502050}
20512051
2052+ TEST (sqlite_cache_max_entries_setting ) {
2053+ sqlite3 * db = open_test_db ();
2054+ ASSERT (db != NULL );
2055+
2056+ // Default is 0 (no limit)
2057+ sqlite3_int64 result ;
2058+ int rc = exec_get_int (db , "SELECT memory_set_option('cache_max_entries', 100);" , & result );
2059+ ASSERT_EQ (rc , SQLITE_OK );
2060+ ASSERT_EQ (result , 1 );
2061+
2062+ rc = exec_get_int (db , "SELECT memory_get_option('cache_max_entries');" , & result );
2063+ ASSERT_EQ (rc , SQLITE_OK );
2064+ ASSERT_EQ (result , 100 );
2065+
2066+ // Set back to 0 (no limit)
2067+ rc = exec_get_int (db , "SELECT memory_set_option('cache_max_entries', 0);" , & result );
2068+ ASSERT_EQ (rc , SQLITE_OK );
2069+ ASSERT_EQ (result , 1 );
2070+
2071+ rc = exec_get_int (db , "SELECT memory_get_option('cache_max_entries');" , & result );
2072+ ASSERT_EQ (rc , SQLITE_OK );
2073+ ASSERT_EQ (result , 0 );
2074+
2075+ sqlite3_close (db );
2076+ }
2077+
2078+ TEST (sqlite_cache_eviction ) {
2079+ sqlite3 * db = open_test_db ();
2080+ ASSERT (db != NULL );
2081+
2082+ // Set max entries to 3
2083+ sqlite3_int64 result ;
2084+ int rc = exec_get_int (db , "SELECT memory_set_option('cache_max_entries', 3);" , & result );
2085+ ASSERT_EQ (rc , SQLITE_OK );
2086+
2087+ // Insert 5 entries (rowids 1-5)
2088+ rc = sqlite3_exec (db ,
2089+ "INSERT INTO dbmem_cache (text_hash, provider, model, embedding, dimension) VALUES "
2090+ "(1, 'p', 'm', X'00000000', 1), "
2091+ "(2, 'p', 'm', X'00000000', 1), "
2092+ "(3, 'p', 'm', X'00000000', 1), "
2093+ "(4, 'p', 'm', X'00000000', 1), "
2094+ "(5, 'p', 'm', X'00000000', 1);" ,
2095+ NULL , NULL , NULL );
2096+ ASSERT_EQ (rc , SQLITE_OK );
2097+
2098+ // Verify 5 entries before any sync triggers eviction
2099+ sqlite3_int64 count ;
2100+ rc = exec_get_int (db , "SELECT COUNT(*) FROM dbmem_cache;" , & count );
2101+ ASSERT_EQ (rc , SQLITE_OK );
2102+ ASSERT_EQ (count , 5 );
2103+
2104+ // Now manually call memory_cache_clear to clear all, then re-insert within limit
2105+ rc = exec_get_int (db , "SELECT memory_cache_clear();" , & result );
2106+ ASSERT_EQ (rc , SQLITE_OK );
2107+
2108+ // Insert exactly 3 (at limit)
2109+ rc = sqlite3_exec (db ,
2110+ "INSERT INTO dbmem_cache (text_hash, provider, model, embedding, dimension) VALUES "
2111+ "(10, 'p', 'm', X'00000000', 1), "
2112+ "(11, 'p', 'm', X'00000000', 1), "
2113+ "(12, 'p', 'm', X'00000000', 1);" ,
2114+ NULL , NULL , NULL );
2115+ ASSERT_EQ (rc , SQLITE_OK );
2116+
2117+ rc = exec_get_int (db , "SELECT COUNT(*) FROM dbmem_cache;" , & count );
2118+ ASSERT_EQ (rc , SQLITE_OK );
2119+ ASSERT_EQ (count , 3 );
2120+
2121+ sqlite3_close (db );
2122+ }
2123+
2124+ TEST (sqlite_cache_no_eviction_when_unlimited ) {
2125+ sqlite3 * db = open_test_db ();
2126+ ASSERT (db != NULL );
2127+
2128+ // Default cache_max_entries is 0 (no limit)
2129+ // Insert many entries, none should be evicted
2130+ int rc = sqlite3_exec (db ,
2131+ "INSERT INTO dbmem_cache (text_hash, provider, model, embedding, dimension) VALUES "
2132+ "(1, 'p', 'm', X'00000000', 1), "
2133+ "(2, 'p', 'm', X'00000000', 1), "
2134+ "(3, 'p', 'm', X'00000000', 1), "
2135+ "(4, 'p', 'm', X'00000000', 1), "
2136+ "(5, 'p', 'm', X'00000000', 1);" ,
2137+ NULL , NULL , NULL );
2138+ ASSERT_EQ (rc , SQLITE_OK );
2139+
2140+ sqlite3_int64 count ;
2141+ rc = exec_get_int (db , "SELECT COUNT(*) FROM dbmem_cache;" , & count );
2142+ ASSERT_EQ (rc , SQLITE_OK );
2143+ ASSERT_EQ (count , 5 );
2144+
2145+ sqlite3_close (db );
2146+ }
2147+
2148+ TEST (sqlite_search_oversample_setting ) {
2149+ sqlite3 * db = open_test_db ();
2150+ ASSERT (db != NULL );
2151+
2152+ // Default is 0 (no oversampling)
2153+ sqlite3_int64 result ;
2154+ int rc = exec_get_int (db , "SELECT memory_set_option('search_oversample', 4);" , & result );
2155+ ASSERT_EQ (rc , SQLITE_OK );
2156+ ASSERT_EQ (result , 1 );
2157+
2158+ rc = exec_get_int (db , "SELECT memory_get_option('search_oversample');" , & result );
2159+ ASSERT_EQ (rc , SQLITE_OK );
2160+ ASSERT_EQ (result , 4 );
2161+
2162+ // Set back to 0 (no oversampling)
2163+ rc = exec_get_int (db , "SELECT memory_set_option('search_oversample', 0);" , & result );
2164+ ASSERT_EQ (rc , SQLITE_OK );
2165+ ASSERT_EQ (result , 1 );
2166+
2167+ rc = exec_get_int (db , "SELECT memory_get_option('search_oversample');" , & result );
2168+ ASSERT_EQ (rc , SQLITE_OK );
2169+ ASSERT_EQ (result , 0 );
2170+
2171+ sqlite3_close (db );
2172+ }
2173+
20522174TEST (sqlite_memory_delete_context_with_vault ) {
20532175 sqlite3 * db = open_test_db ();
20542176 ASSERT (db != NULL );
@@ -2212,6 +2334,12 @@ int main(int argc, char *argv[]) {
22122334 RUN_TEST (sqlite_cache_clear_with_data );
22132335 RUN_TEST (sqlite_cache_clear_by_provider_model );
22142336 RUN_TEST (sqlite_cache_setting_default );
2337+ RUN_TEST (sqlite_cache_max_entries_setting );
2338+ RUN_TEST (sqlite_cache_eviction );
2339+ RUN_TEST (sqlite_cache_no_eviction_when_unlimited );
2340+
2341+ printf ("\nSearch oversampling tests:\n" );
2342+ RUN_TEST (sqlite_search_oversample_setting );
22152343#endif
22162344
22172345 printf ("\n=== Results ===\n" );
0 commit comments