@@ -241,7 +241,11 @@ impl<'a> MoveStream<'a> {
241241 }
242242 move_byte => {
243243 // Parse actual chess move
244- if let Some ( chess_move) = self . position . legal_moves ( ) . get ( move_byte as usize ) {
244+ // Get legal moves once instead of on every iteration
245+ let legal_moves = self . position . legal_moves ( ) ;
246+ if let Some ( chess_move) = legal_moves. get ( move_byte as usize ) {
247+ // Only clone position when we're returning it
248+ // This avoids cloning on every move in the game
245249 let san = SanPlus :: from_move_and_play_unchecked ( & mut self . position , chess_move) ;
246250 let move_string = san. to_string ( ) ;
247251 self . index += 1 ;
@@ -461,24 +465,22 @@ pub async fn search_position(
461465
462466 let position_query = position_query. unwrap ( ) ;
463467
464- // Cache management
468+ // Cache management with LRU
465469 const DISABLE_CACHE : bool = false ;
466470
467471 if !DISABLE_CACHE {
468472 let cache_key = ( query. clone ( ) , file. clone ( ) ) ;
469473
470474 // Return cached results if available
471- if let Some ( cached_result) = state. line_cache . get ( & cache_key) {
475+ // LRU cache automatically updates access order on get()
476+ let mut cache = state. line_cache . lock ( ) . unwrap ( ) ;
477+ if let Some ( cached_result) = cache. get ( & cache_key) {
472478 info ! ( "Using cached results: {} stats, {} games" ,
473479 cached_result. 0 . len( ) , cached_result. 1 . len( ) ) ;
474480 return Ok ( cached_result. clone ( ) ) ;
475481 }
476-
477- // Clear cache if it gets too large
478- if state. line_cache . len ( ) > 100 {
479- info ! ( "Clearing cache (too many entries: {})" , state. line_cache. len( ) ) ;
480- state. line_cache . clear ( ) ;
481- }
482+ // LRU cache automatically evicts least recently used entries when capacity is reached
483+ // No need for manual size checking and clearing
482484 }
483485
484486 // Handle request cancellation
@@ -896,7 +898,8 @@ pub async fn search_position(
896898 let result = ( openings. clone ( ) , normalized_games. clone ( ) ) ;
897899 if !DISABLE_CACHE {
898900 let cache_key = ( query. clone ( ) , file. clone ( ) ) ;
899- state. line_cache . insert ( cache_key. clone ( ) , result. clone ( ) ) ;
901+ // LRU cache automatically evicts least recently used entry if at capacity
902+ state. line_cache . lock ( ) . unwrap ( ) . push ( cache_key. clone ( ) , result. clone ( ) ) ;
900903 info ! ( "Cached position search results for FEN '{}': {} position stats, {} games" ,
901904 cache_key. 0 . position. as_ref( ) . map( |p| p. fen. as_str( ) ) . unwrap_or( "None" ) ,
902905 openings. len( ) ,
@@ -939,7 +942,7 @@ pub async fn is_position_in_db(
939942 info ! ( "Checking if position exists in DB with FEN: {}" , pos_query. fen) ;
940943 }
941944
942- if let Some ( pos) = state. line_cache . get ( & ( query. clone ( ) , file. clone ( ) ) ) {
945+ if let Some ( pos) = state. line_cache . lock ( ) . unwrap ( ) . get ( & ( query. clone ( ) , file. clone ( ) ) ) {
943946 info ! ( "Using cached result for position existence check: {}" , !pos. 0 . is_empty( ) ) ;
944947 return Ok ( !pos. 0 . is_empty ( ) ) ;
945948 }
@@ -1010,7 +1013,7 @@ pub async fn is_position_in_db(
10101013
10111014 if !exists {
10121015 info ! ( "Position not found in DB, caching empty result" ) ;
1013- state. line_cache . insert ( ( query, file) , ( vec ! [ ] , vec ! [ ] ) ) ;
1016+ state. line_cache . lock ( ) . unwrap ( ) . push ( ( query, file) , ( vec ! [ ] , vec ! [ ] ) ) ;
10141017 } else {
10151018 info ! ( "Position found in DB" ) ;
10161019 }
0 commit comments