@@ -1454,10 +1454,15 @@ pub mod sparse256 {
14541454 /// - Skip entire 32-element HEEL blocks if the 8×8 super-block is empty
14551455 /// - Skip 4-element TWIG blocks if the palette bit is 0
14561456 /// - Only compute exact distance for active palette entries
1457- pub fn hhtl_cascade_search (
1457+ ///
1458+ /// `score_fn`: callback that computes the actual score for a (row, col) pair.
1459+ /// This is where the LEAF level lives — LanceDB vector search, DistanceMatrix
1460+ /// lookup, or BF16 dot product. The cascade doesn't know or care which.
1461+ pub fn hhtl_cascade_search < F : Fn ( u8 , u8 ) -> f32 > (
14581462 palette : & Palette64 ,
14591463 query_row : u8 ,
14601464 scores : & mut [ f32 ; 256 ] ,
1465+ score_fn : F ,
14611466 ) -> usize {
14621467 let heel_row = query_row / 32 ;
14631468 let hip_row = ( query_row / 4 ) % 8 ;
@@ -1478,14 +1483,11 @@ pub mod sparse256 {
14781483 let block_col = bits. trailing_zeros ( ) as usize ;
14791484 bits &= bits - 1 ;
14801485
1481- // This block is active — compute 4 scores
14821486 let base_col = block_col * 4 ;
14831487 for k in 0 ..4 {
14841488 let col = base_col + k;
14851489 if col < 256 {
1486- // Placeholder: actual score computation goes here
1487- // In production: ZeckF8 distance or BF16 dot product
1488- scores[ col] = 1.0 ;
1490+ scores[ col] = score_fn ( query_row, col as u8 ) ;
14891491 computed += 1 ;
14901492 }
14911493 }
@@ -1864,15 +1866,16 @@ mod tests {
18641866 }
18651867
18661868 let mut scores = [ 0.0f32 ; 256 ] ;
1867- let computed = hhtl_cascade_search ( & palette, 0 , & mut scores) ;
1869+ let score_fn = |row : u8 , col : u8 | -> f32 { 1.0 - ( row as f32 - col as f32 ) . abs ( ) / 256.0 } ;
1870+ let computed = hhtl_cascade_search ( & palette, 0 , & mut scores, & score_fn) ;
18681871
18691872 eprintln ! ( "HHTL cascade: computed {} of 256 scores" , computed) ;
18701873
18711874 // Only 4 scores should be computed (one block of 4)
18721875 assert_eq ! ( computed, 4 , "Should only compute active block entries" ) ;
18731876
18741877 // Row 128 → block_row = 128/32*8 + (128/4)%8 = 4*8 + 0 = 32
1875- let computed2 = hhtl_cascade_search ( & palette, 128 , & mut scores) ;
1878+ let computed2 = hhtl_cascade_search ( & palette, 128 , & mut scores, & score_fn ) ;
18761879 assert_eq ! ( computed2, 4 ) ;
18771880 }
18781881
0 commit comments