@@ -34,8 +34,8 @@ std::string SearchHandler::HandleSearch(const query::Query& query, ConnectionCon
3434 // Try cache lookup first
3535 auto cache_lookup_start = std::chrono::high_resolution_clock::now ();
3636 if (ctx_.cache_manager != nullptr && ctx_.cache_manager ->IsEnabled ()) {
37- auto cached_result = ctx_.cache_manager ->Lookup (query);
38- if (cached_result .has_value ()) {
37+ auto cached_lookup = ctx_.cache_manager ->LookupWithMetadata (query);
38+ if (cached_lookup .has_value ()) {
3939 // Cache hit! Return cached result
4040 storage::DocumentStore* current_doc_store = nullptr ;
4141 index::Index* dummy_index = nullptr ;
@@ -50,22 +50,29 @@ std::string SearchHandler::HandleSearch(const query::Query& query, ConnectionCon
5050 double cache_lookup_time_ms =
5151 std::chrono::duration<double , std::milli>(cache_lookup_end - cache_lookup_start).count ();
5252
53+ // Apply pagination to cached results
54+ // Cache stores full results (before pagination) to allow different OFFSET/LIMIT on same query
55+ auto full_results = cached_lookup.value ().results ;
56+ size_t total_results = full_results.size ();
57+ auto paginated_results = query::ResultSorter::SortAndPaginate (full_results, *current_doc_store, query);
58+
5359 if (conn_ctx.debug_mode ) {
5460 query::DebugInfo debug_info;
5561 debug_info.query_time_ms = cache_lookup_time_ms;
56- debug_info.final_results = cached_result. value () .size ();
62+ debug_info.final_results = paginated_results .size ();
5763
58- // Cache hit debug info
64+ // Cache hit debug info with actual metadata
65+ auto now = std::chrono::steady_clock::now ();
5966 debug_info.cache_info .status = query::CacheDebugInfo::Status::HIT;
60- debug_info.cache_info .cache_age_ms = 0.0 ; // TODO: Calculate from cache entry timestamp
61- debug_info.cache_info .cache_saved_ms = 0.0 ; // TODO: Calculate from query cost in cache entry
67+ debug_info.cache_info .cache_age_ms =
68+ std::chrono::duration<double , std::milli>(now - cached_lookup.value ().created_at ).count ();
69+ debug_info.cache_info .cache_saved_ms = cached_lookup.value ().query_cost_ms ;
6270
63- return ResponseFormatter::FormatSearchResponse (cached_result. value (), cached_result. value (). size () ,
64- current_doc_store, &debug_info);
71+ return ResponseFormatter::FormatSearchResponse (paginated_results, total_results, current_doc_store ,
72+ &debug_info);
6573 }
6674
67- return ResponseFormatter::FormatSearchResponse (cached_result.value (), cached_result.value ().size (),
68- current_doc_store);
75+ return ResponseFormatter::FormatSearchResponse (paginated_results, total_results, current_doc_store);
6976 }
7077 }
7178 }
@@ -290,6 +297,35 @@ std::string SearchHandler::HandleCount(const query::Query& query, ConnectionCont
290297 return ResponseFormatter::FormatError (" Server is loading, please try again later" );
291298 }
292299
300+ // Try cache lookup first
301+ auto cache_lookup_start = std::chrono::high_resolution_clock::now ();
302+ if (ctx_.cache_manager != nullptr && ctx_.cache_manager ->IsEnabled ()) {
303+ auto cached_lookup = ctx_.cache_manager ->LookupWithMetadata (query);
304+ if (cached_lookup.has_value ()) {
305+ // Cache hit! Return count from cached result
306+ auto cache_lookup_end = std::chrono::high_resolution_clock::now ();
307+ double cache_lookup_time_ms =
308+ std::chrono::duration<double , std::milli>(cache_lookup_end - cache_lookup_start).count ();
309+
310+ if (conn_ctx.debug_mode ) {
311+ query::DebugInfo debug_info;
312+ debug_info.query_time_ms = cache_lookup_time_ms;
313+ debug_info.final_results = cached_lookup.value ().results .size ();
314+
315+ // Cache hit debug info with actual metadata
316+ auto now = std::chrono::steady_clock::now ();
317+ debug_info.cache_info .status = query::CacheDebugInfo::Status::HIT;
318+ debug_info.cache_info .cache_age_ms =
319+ std::chrono::duration<double , std::milli>(now - cached_lookup.value ().created_at ).count ();
320+ debug_info.cache_info .cache_saved_ms = cached_lookup.value ().query_cost_ms ;
321+
322+ return ResponseFormatter::FormatCountResponse (cached_lookup.value ().results .size (), &debug_info);
323+ }
324+
325+ return ResponseFormatter::FormatCountResponse (cached_lookup.value ().results .size ());
326+ }
327+ }
328+
293329 // Get table context
294330 index::Index* current_index = nullptr ;
295331 storage::DocumentStore* current_doc_store = nullptr ;
@@ -364,11 +400,37 @@ std::string SearchHandler::HandleCount(const query::Query& query, ConnectionCont
364400 results = ApplyFilters (results, query.filters , current_doc_store);
365401 }
366402
403+ // Calculate query execution time
404+ auto end_time = std::chrono::high_resolution_clock::now ();
405+ double query_time_ms = std::chrono::duration<double , std::milli>(end_time - start_time).count ();
406+
407+ // Store in cache if enabled
408+ if (ctx_.cache_manager != nullptr && ctx_.cache_manager ->IsEnabled ()) {
409+ // Collect all ngrams from term_infos
410+ std::set<std::string> all_ngrams;
411+ for (const auto & term_info : term_infos) {
412+ all_ngrams.insert (term_info.ngrams .begin (), term_info.ngrams .end ());
413+ }
414+
415+ // Insert result into cache (COUNT caches the full result set like SEARCH)
416+ ctx_.cache_manager ->Insert (query, results, all_ngrams, query_time_ms);
417+ }
418+
367419 // Calculate final debug info
368420 if (conn_ctx.debug_mode ) {
369- auto end_time = std::chrono::high_resolution_clock::now ();
370- debug_info.query_time_ms = std::chrono::duration<double , std::milli>(end_time - start_time).count ();
421+ debug_info.query_time_ms = query_time_ms;
371422 debug_info.index_time_ms = std::chrono::duration<double , std::milli>(end_time - index_start).count ();
423+
424+ // Cache debug info
425+ if (ctx_.cache_manager != nullptr && ctx_.cache_manager ->IsEnabled ()) {
426+ // Cache was enabled but missed (either not found or invalidated)
427+ debug_info.cache_info .status = query::CacheDebugInfo::Status::MISS_NOT_FOUND;
428+ debug_info.cache_info .query_cost_ms = query_time_ms;
429+ } else {
430+ // Cache disabled
431+ debug_info.cache_info .status = query::CacheDebugInfo::Status::MISS_DISABLED;
432+ }
433+
372434 return ResponseFormatter::FormatCountResponse (results.size (), &debug_info);
373435 }
374436
0 commit comments