@@ -1706,7 +1706,8 @@ mod tests {
1706
1706
1707
1707
let old_reader = index. reader ( ) ?;
1708
1708
1709
- let id_exists = |id| id % 3 != 0 ; // 0 does not exist
1709
+ // Every 3rd doc has only id field
1710
+ let id_is_full_doc = |id| id % 3 != 0 ;
1710
1711
1711
1712
let multi_text_field_text1 = "test1 test2 test3 test1 test2 test3" ;
1712
1713
// rotate left
@@ -1722,7 +1723,7 @@ mod tests {
1722
1723
let facet = Facet :: from ( & ( "/cola/" . to_string ( ) + & id. to_string ( ) ) ) ;
1723
1724
let ip = ip_from_id ( id) ;
1724
1725
1725
- if !id_exists ( id) {
1726
+ if !id_is_full_doc ( id) {
1726
1727
// every 3rd doc has no ip field
1727
1728
index_writer. add_document ( doc ! (
1728
1729
id_field=>id,
@@ -1842,7 +1843,7 @@ mod tests {
1842
1843
1843
1844
let num_docs_with_values = expected_ids_and_num_occurrences
1844
1845
. iter ( )
1845
- . filter ( |( id, _id_occurrences) | id_exists ( * * id) )
1846
+ . filter ( |( id, _id_occurrences) | id_is_full_doc ( * * id) )
1846
1847
. map ( |( _, id_occurrences) | * id_occurrences as usize )
1847
1848
. sum :: < usize > ( ) ;
1848
1849
@@ -1866,7 +1867,7 @@ mod tests {
1866
1867
if force_end_merge && num_segments_before_merge > 1 && num_segments_after_merge == 1 {
1867
1868
let mut expected_multi_ips: Vec < _ > = id_list
1868
1869
. iter ( )
1869
- . filter ( |id| id_exists ( * * id) )
1870
+ . filter ( |id| id_is_full_doc ( * * id) )
1870
1871
. flat_map ( |id| vec ! [ ip_from_id( * id) , ip_from_id( * id) ] )
1871
1872
. collect ( ) ;
1872
1873
assert_eq ! ( num_ips, expected_multi_ips. len( ) as u32 ) ;
@@ -1904,7 +1905,7 @@ mod tests {
1904
1905
let expected_ips = expected_ids_and_num_occurrences
1905
1906
. keys ( )
1906
1907
. flat_map ( |id| {
1907
- if !id_exists ( * id) {
1908
+ if !id_is_full_doc ( * id) {
1908
1909
None
1909
1910
} else {
1910
1911
Some ( Ipv6Addr :: from_u128 ( * id as u128 ) )
@@ -1916,7 +1917,7 @@ mod tests {
1916
1917
let expected_ips = expected_ids_and_num_occurrences
1917
1918
. keys ( )
1918
1919
. filter_map ( |id| {
1919
- if !id_exists ( * id) {
1920
+ if !id_is_full_doc ( * id) {
1920
1921
None
1921
1922
} else {
1922
1923
Some ( Ipv6Addr :: from_u128 ( * id as u128 ) )
@@ -1951,7 +1952,7 @@ mod tests {
1951
1952
let id = id_reader. first ( doc) . unwrap ( ) ;
1952
1953
1953
1954
let vals: Vec < u64 > = ff_reader. values_for_doc ( doc) . collect ( ) ;
1954
- if id_exists ( id) {
1955
+ if id_is_full_doc ( id) {
1955
1956
assert_eq ! ( vals. len( ) , 2 ) ;
1956
1957
assert_eq ! ( vals[ 0 ] , vals[ 1 ] ) ;
1957
1958
assert ! ( expected_ids_and_num_occurrences. contains_key( & vals[ 0 ] ) ) ;
@@ -1961,7 +1962,7 @@ mod tests {
1961
1962
}
1962
1963
1963
1964
let bool_vals: Vec < bool > = bool_ff_reader. values_for_doc ( doc) . collect ( ) ;
1964
- if id_exists ( id) {
1965
+ if id_is_full_doc ( id) {
1965
1966
assert_eq ! ( bool_vals. len( ) , 2 ) ;
1966
1967
assert_ne ! ( bool_vals[ 0 ] , bool_vals[ 1 ] ) ;
1967
1968
} else {
@@ -1990,7 +1991,7 @@ mod tests {
1990
1991
. as_u64 ( )
1991
1992
. unwrap ( ) ;
1992
1993
assert ! ( expected_ids_and_num_occurrences. contains_key( & id) ) ;
1993
- if id_exists ( id) {
1994
+ if id_is_full_doc ( id) {
1994
1995
let id2 = store_reader
1995
1996
. get :: < TantivyDocument > ( doc_id)
1996
1997
. unwrap ( )
@@ -2037,7 +2038,7 @@ mod tests {
2037
2038
let ( existing_id, count) = ( * id, * count) ;
2038
2039
let get_num_hits = |field| do_search ( & existing_id. to_string ( ) , field) . len ( ) as u64 ;
2039
2040
assert_eq ! ( get_num_hits( id_field) , count) ;
2040
- if !id_exists ( existing_id) {
2041
+ if !id_is_full_doc ( existing_id) {
2041
2042
continue ;
2042
2043
}
2043
2044
assert_eq ! ( get_num_hits( text_field) , count) ;
@@ -2087,7 +2088,7 @@ mod tests {
2087
2088
//
2088
2089
for ( existing_id, count) in & expected_ids_and_num_occurrences {
2089
2090
let ( existing_id, count) = ( * existing_id, * count) ;
2090
- if !id_exists ( existing_id) {
2091
+ if !id_is_full_doc ( existing_id) {
2091
2092
continue ;
2092
2093
}
2093
2094
let do_search_ip_field = |term : & str | do_search ( term, ip_field) . len ( ) as u64 ;
@@ -2104,34 +2105,84 @@ mod tests {
2104
2105
}
2105
2106
}
2106
2107
2107
- // assert data is like expected
2108
+ // Range query
2108
2109
//
2109
- for ( existing_id, count) in expected_ids_and_num_occurrences. iter ( ) . take ( 10 ) {
2110
- let ( existing_id, count) = ( * existing_id, * count) ;
2111
- if !id_exists ( existing_id) {
2112
- continue ;
2113
- }
2114
- let gen_query_inclusive = |field : & str , from : Ipv6Addr , to : Ipv6Addr | {
2115
- format ! ( "{}:[{} TO {}]" , field, & from. to_string( ) , & to. to_string( ) )
2110
+ // Take half as sample
2111
+ let mut sample: Vec < _ > = expected_ids_and_num_occurrences. iter ( ) . collect ( ) ;
2112
+ sample. sort_by_key ( |( k, _num_occurences) | * k) ;
2113
+ // sample.truncate(sample.len() / 2);
2114
+ if !sample. is_empty ( ) {
2115
+ let ( left_sample, right_sample) = sample. split_at ( sample. len ( ) / 2 ) ;
2116
+
2117
+ let expected_count = |sample : & [ ( & u64 , & u64 ) ] | {
2118
+ sample
2119
+ . iter ( )
2120
+ . filter ( |( id, _) | id_is_full_doc ( * * id) )
2121
+ . map ( |( _id, num_occurences) | * * num_occurences)
2122
+ . sum :: < u64 > ( )
2116
2123
} ;
2117
- let ip = ip_from_id ( existing_id) ;
2118
-
2119
- let do_search_ip_field = |term : & str | do_search ( term, ip_field) . len ( ) as u64 ;
2120
- // Range query on single value field
2121
- let query = gen_query_inclusive ( "ip" , ip, ip) ;
2122
- assert_eq ! ( do_search_ip_field( & query) , count) ;
2123
-
2124
- // Range query on multi value field
2125
- let query = gen_query_inclusive ( "ips" , ip, ip) ;
2124
+ fn gen_query_inclusive < T1 : ToString , T2 : ToString > (
2125
+ field : & str ,
2126
+ from : T1 ,
2127
+ to : T2 ,
2128
+ ) -> String {
2129
+ format ! ( "{}:[{} TO {}]" , field, & from. to_string( ) , & to. to_string( ) )
2130
+ }
2126
2131
2127
- assert_eq ! ( do_search_ip_field( & query) , count) ;
2132
+ // Query first half
2133
+ if left_sample. len ( ) >= 1 {
2134
+ let expected_count = expected_count ( left_sample) ;
2135
+
2136
+ let start_range = * left_sample[ 0 ] . 0 ;
2137
+ let end_range = * left_sample. last ( ) . unwrap ( ) . 0 ;
2138
+ let query = gen_query_inclusive ( "id_opt" , start_range, end_range) ;
2139
+ assert_eq ! ( do_search( & query, id_opt_field) . len( ) as u64 , expected_count) ;
2140
+
2141
+ // Range query on ip field
2142
+ let ip1 = ip_from_id ( start_range) ;
2143
+ let ip2 = ip_from_id ( end_range) ;
2144
+ let do_search_ip_field = |term : & str | do_search ( term, ip_field) . len ( ) as u64 ;
2145
+ let query = gen_query_inclusive ( "ip" , ip1, ip2) ;
2146
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2147
+ let query = gen_query_inclusive ( "ip" , "*" , ip2) ;
2148
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2149
+ // Range query on multi value field
2150
+ let query = gen_query_inclusive ( "ips" , ip1, ip2) ;
2151
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2152
+ let query = gen_query_inclusive ( "ips" , "*" , ip2) ;
2153
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2154
+ }
2155
+ // Query second half
2156
+ if right_sample. len ( ) >= 1 {
2157
+ let expected_count = expected_count ( right_sample) ;
2158
+ let start_range = * right_sample[ 0 ] . 0 ;
2159
+ let end_range = * right_sample. last ( ) . unwrap ( ) . 0 ;
2160
+ // Range query on id opt field
2161
+ let query =
2162
+ gen_query_inclusive ( "id_opt" , start_range. to_string ( ) , end_range. to_string ( ) ) ;
2163
+ assert_eq ! ( do_search( & query, id_opt_field) . len( ) as u64 , expected_count) ;
2164
+
2165
+ // Range query on ip field
2166
+ let ip1 = ip_from_id ( start_range) ;
2167
+ let ip2 = ip_from_id ( end_range) ;
2168
+ let do_search_ip_field = |term : & str | do_search ( term, ip_field) . len ( ) as u64 ;
2169
+ let query = gen_query_inclusive ( "ip" , ip1, ip2) ;
2170
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2171
+ let query = gen_query_inclusive ( "ip" , ip1, "*" ) ;
2172
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2173
+ // Range query on multi value field
2174
+ let query = gen_query_inclusive ( "ips" , ip1, ip2) ;
2175
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2176
+ let query = gen_query_inclusive ( "ips" , ip1, "*" ) ;
2177
+ assert_eq ! ( do_search_ip_field( & query) , expected_count) ;
2178
+ }
2128
2179
}
2129
2180
2130
2181
// ip range query on fast field
2131
2182
//
2132
2183
for ( existing_id, count) in expected_ids_and_num_occurrences. iter ( ) . take ( 10 ) {
2133
2184
let ( existing_id, count) = ( * existing_id, * count) ;
2134
- if !id_exists ( existing_id) {
2185
+ if !id_is_full_doc ( existing_id) {
2135
2186
continue ;
2136
2187
}
2137
2188
let gen_query_inclusive = |field : & str , from : Ipv6Addr , to : Ipv6Addr | {
@@ -2159,7 +2210,7 @@ mod tests {
2159
2210
. first_or_default_col ( 9999 ) ;
2160
2211
for doc_id in segment_reader. doc_ids_alive ( ) {
2161
2212
let id = ff_reader. get_val ( doc_id) ;
2162
- if !id_exists ( id) {
2213
+ if !id_is_full_doc ( id) {
2163
2214
continue ;
2164
2215
}
2165
2216
let facet_ords: Vec < u64 > = facet_reader. facet_ords ( doc_id) . collect ( ) ;
@@ -2197,6 +2248,12 @@ mod tests {
2197
2248
Ok ( index)
2198
2249
}
2199
2250
2251
+ #[ test]
2252
+ fn test_fast_field_range ( ) {
2253
+ let ops: Vec < _ > = ( 0 ..1000 ) . map ( |id| IndexingOp :: AddDoc { id } ) . collect ( ) ;
2254
+ assert ! ( test_operation_strategy( & ops, false , true ) . is_ok( ) ) ;
2255
+ }
2256
+
2200
2257
#[ test]
2201
2258
fn test_sort_index_on_opt_field_regression ( ) {
2202
2259
assert ! ( test_operation_strategy(
0 commit comments