1use std::net::Ipv6Addr;
2use std::sync::Arc;
3
4use fastfield_codecs::{open, open_u128, Column};
5
6use super::multivalued::MultiValuedFastFieldReader;
7use crate::directory::{CompositeFile, FileSlice};
8use crate::fastfield::{BytesFastFieldReader, FastFieldNotAvailableError, FastValue};
9use crate::schema::{Cardinality, Field, FieldType, Schema};
10use crate::space_usage::PerFieldSpaceUsage;
11use crate::{DateTime, TantivyError};
12
13#[derive(Clone)]
18pub struct FastFieldReaders {
19 schema: Schema,
20 fast_fields_composite: CompositeFile,
21}
22#[derive(Eq, PartialEq, Debug)]
23pub(crate) enum FastType {
24 I64,
25 U64,
26 U128,
27 F64,
28 Bool,
29 Date,
30}
31
32pub(crate) fn type_and_cardinality(field_type: &FieldType) -> Option<(FastType, Cardinality)> {
33 match field_type {
34 FieldType::U64(options) => options
35 .get_fastfield_cardinality()
36 .map(|cardinality| (FastType::U64, cardinality)),
37 FieldType::I64(options) => options
38 .get_fastfield_cardinality()
39 .map(|cardinality| (FastType::I64, cardinality)),
40 FieldType::F64(options) => options
41 .get_fastfield_cardinality()
42 .map(|cardinality| (FastType::F64, cardinality)),
43 FieldType::Bool(options) => options
44 .get_fastfield_cardinality()
45 .map(|cardinality| (FastType::Bool, cardinality)),
46 FieldType::Date(options) => options
47 .get_fastfield_cardinality()
48 .map(|cardinality| (FastType::Date, cardinality)),
49 FieldType::Facet(_) => Some((FastType::U64, Cardinality::MultiValues)),
50 FieldType::Str(options) if options.is_fast() => {
51 Some((FastType::U64, Cardinality::MultiValues))
52 }
53 FieldType::IpAddr(options) => options
54 .get_fastfield_cardinality()
55 .map(|cardinality| (FastType::U128, cardinality)),
56 _ => None,
57 }
58}
59
60impl FastFieldReaders {
61 pub(crate) fn new(schema: Schema, fast_fields_composite: CompositeFile) -> FastFieldReaders {
62 FastFieldReaders {
63 schema,
64 fast_fields_composite,
65 }
66 }
67
68 pub(crate) fn space_usage(&self) -> PerFieldSpaceUsage {
69 self.fast_fields_composite.space_usage()
70 }
71
72 #[doc(hidden)]
73 pub fn fast_field_data(&self, field: Field, idx: usize) -> crate::Result<FileSlice> {
74 self.fast_fields_composite
75 .open_read_with_idx(field, idx)
76 .ok_or_else(|| {
77 let field_name = self.schema.get_field_entry(field).name();
78 TantivyError::SchemaError(format!("Field({}) data was not found", field_name))
79 })
80 }
81
82 fn check_type(
83 &self,
84 field: Field,
85 expected_fast_type: FastType,
86 expected_cardinality: Cardinality,
87 ) -> crate::Result<()> {
88 let field_entry = self.schema.get_field_entry(field);
89 let (fast_type, cardinality) =
90 type_and_cardinality(field_entry.field_type()).ok_or_else(|| {
91 crate::TantivyError::SchemaError(format!(
92 "Field {:?} is not a fast field.",
93 field_entry.name()
94 ))
95 })?;
96 if fast_type != expected_fast_type {
97 return Err(crate::TantivyError::SchemaError(format!(
98 "Field {:?} is of type {:?}, expected {:?}.",
99 field_entry.name(),
100 fast_type,
101 expected_fast_type
102 )));
103 }
104 if cardinality != expected_cardinality {
105 return Err(crate::TantivyError::SchemaError(format!(
106 "Field {:?} is of cardinality {:?}, expected {:?}.",
107 field_entry.name(),
108 cardinality,
109 expected_cardinality
110 )));
111 }
112 Ok(())
113 }
114
115 pub(crate) fn typed_fast_field_reader_with_idx<TFastValue: FastValue>(
116 &self,
117 field: Field,
118 index: usize,
119 ) -> crate::Result<Arc<dyn Column<TFastValue>>> {
120 let fast_field_slice = self.fast_field_data(field, index)?;
121 let bytes = fast_field_slice.read_bytes()?;
122 let column = fastfield_codecs::open(bytes)?;
123 Ok(column)
124 }
125
126 pub(crate) fn typed_fast_field_reader<TFastValue: FastValue>(
127 &self,
128 field: Field,
129 ) -> crate::Result<Arc<dyn Column<TFastValue>>> {
130 self.typed_fast_field_reader_with_idx(field, 0)
131 }
132
133 pub(crate) fn typed_fast_field_multi_reader<TFastValue: FastValue>(
134 &self,
135 field: Field,
136 ) -> crate::Result<MultiValuedFastFieldReader<TFastValue>> {
137 let idx_reader = self.typed_fast_field_reader(field)?;
138 let vals_reader = self.typed_fast_field_reader_with_idx(field, 1)?;
139 Ok(MultiValuedFastFieldReader::open(idx_reader, vals_reader))
140 }
141
142 pub fn u64(&self, field: Field) -> crate::Result<Arc<dyn Column<u64>>> {
146 self.check_type(field, FastType::U64, Cardinality::SingleValue)?;
147 self.typed_fast_field_reader(field)
148 }
149
150 pub fn ip_addr(&self, field: Field) -> crate::Result<Arc<dyn Column<Ipv6Addr>>> {
154 self.check_type(field, FastType::U128, Cardinality::SingleValue)?;
155 let bytes = self.fast_field_data(field, 0)?.read_bytes()?;
156 Ok(open_u128::<Ipv6Addr>(bytes)?)
157 }
158
159 pub fn ip_addrs(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<Ipv6Addr>> {
163 self.check_type(field, FastType::U128, Cardinality::MultiValues)?;
164 let idx_reader: Arc<dyn Column<u64>> = self.typed_fast_field_reader(field)?;
165
166 let bytes = self.fast_field_data(field, 1)?.read_bytes()?;
167 let vals_reader = open_u128::<Ipv6Addr>(bytes)?;
168
169 Ok(MultiValuedFastFieldReader::open(idx_reader, vals_reader))
170 }
171
172 pub(crate) fn u128(&self, field: Field) -> crate::Result<Arc<dyn Column<u128>>> {
176 self.check_type(field, FastType::U128, Cardinality::SingleValue)?;
177 let bytes = self.fast_field_data(field, 0)?.read_bytes()?;
178 Ok(open_u128::<u128>(bytes)?)
179 }
180
181 pub fn u128s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u128>> {
185 self.check_type(field, FastType::U128, Cardinality::MultiValues)?;
186 let idx_reader: Arc<dyn Column<u64>> = self.typed_fast_field_reader(field)?;
187
188 let bytes = self.fast_field_data(field, 1)?.read_bytes()?;
189 let vals_reader = open_u128::<u128>(bytes)?;
190
191 Ok(MultiValuedFastFieldReader::open(idx_reader, vals_reader))
192 }
193
194 pub fn u64_lenient(&self, field: Field) -> crate::Result<Arc<dyn Column<u64>>> {
200 self.typed_fast_field_reader(field)
201 }
202
203 pub fn i64(&self, field: Field) -> crate::Result<Arc<dyn Column<i64>>> {
207 self.check_type(field, FastType::I64, Cardinality::SingleValue)?;
208 self.typed_fast_field_reader(field)
209 }
210
211 pub fn date(&self, field: Field) -> crate::Result<Arc<dyn Column<DateTime>>> {
215 self.check_type(field, FastType::Date, Cardinality::SingleValue)?;
216 self.typed_fast_field_reader(field)
217 }
218
219 pub fn f64(&self, field: Field) -> crate::Result<Arc<dyn Column<f64>>> {
223 self.check_type(field, FastType::F64, Cardinality::SingleValue)?;
224 self.typed_fast_field_reader(field)
225 }
226
227 pub fn bool(&self, field: Field) -> crate::Result<Arc<dyn Column<bool>>> {
231 self.check_type(field, FastType::Bool, Cardinality::SingleValue)?;
232 self.typed_fast_field_reader(field)
233 }
234
235 pub fn u64s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u64>> {
239 self.check_type(field, FastType::U64, Cardinality::MultiValues)?;
240 self.typed_fast_field_multi_reader(field)
241 }
242
243 pub fn u64s_lenient(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u64>> {
248 self.typed_fast_field_multi_reader(field)
249 }
250
251 pub fn i64s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<i64>> {
255 self.check_type(field, FastType::I64, Cardinality::MultiValues)?;
256 self.typed_fast_field_multi_reader(field)
257 }
258
259 pub fn f64s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<f64>> {
263 self.check_type(field, FastType::F64, Cardinality::MultiValues)?;
264 self.typed_fast_field_multi_reader(field)
265 }
266
267 pub fn bools(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<bool>> {
271 self.check_type(field, FastType::Bool, Cardinality::MultiValues)?;
272 self.typed_fast_field_multi_reader(field)
273 }
274
275 pub fn dates(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<DateTime>> {
281 self.check_type(field, FastType::Date, Cardinality::MultiValues)?;
282 self.typed_fast_field_multi_reader(field)
283 }
284
285 pub fn bytes(&self, field: Field) -> crate::Result<BytesFastFieldReader> {
289 let field_entry = self.schema.get_field_entry(field);
290 if let FieldType::Bytes(bytes_option) = field_entry.field_type() {
291 if !bytes_option.is_fast() {
292 return Err(crate::TantivyError::SchemaError(format!(
293 "Field {:?} is not a fast field.",
294 field_entry.name()
295 )));
296 }
297 let fast_field_idx_file = self.fast_field_data(field, 0)?;
298 let fast_field_idx_bytes = fast_field_idx_file.read_bytes()?;
299 let idx_reader = open(fast_field_idx_bytes)?;
300 let data = self.fast_field_data(field, 1)?;
301 BytesFastFieldReader::open(idx_reader, data)
302 } else {
303 Err(FastFieldNotAvailableError::new(field_entry).into())
304 }
305 }
306}