nodedb_fts/index/
fieldnorm.rs1use crate::backend::FtsBackend;
8use crate::codec::smallfloat;
9use crate::index::FtsIndex;
10
11impl<B: FtsBackend> FtsIndex<B> {
12 pub fn read_fieldnorm(
16 &self,
17 tid: u32,
18 collection: &str,
19 doc_id: u32,
20 ) -> Result<Option<u32>, B::Error> {
21 let data = self.backend.read_meta(tid, collection, "fieldnorms")?;
22 match data {
23 Some(bytes) if (doc_id as usize) < bytes.len() => {
24 Ok(Some(smallfloat::decode(bytes[doc_id as usize])))
25 }
26 _ => Ok(None),
27 }
28 }
29
30 pub fn write_fieldnorm(
32 &self,
33 tid: u32,
34 collection: &str,
35 doc_id: u32,
36 doc_length: u32,
37 ) -> Result<(), B::Error> {
38 let mut data = self
39 .backend
40 .read_meta(tid, collection, "fieldnorms")?
41 .unwrap_or_default();
42
43 let idx = doc_id as usize;
44 if idx >= data.len() {
45 data.resize(idx + 1, 0);
46 }
47 data[idx] = smallfloat::encode(doc_length);
48
49 self.backend
50 .write_meta(tid, collection, "fieldnorms", &data)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use crate::backend::memory::MemoryBackend;
57 use crate::codec::smallfloat;
58 use crate::index::FtsIndex;
59
60 const T: u32 = 1;
61
62 #[test]
63 fn fieldnorm_roundtrip() {
64 let idx = FtsIndex::new(MemoryBackend::new());
65 idx.write_fieldnorm(T, "col", 0, 100).unwrap();
66 idx.write_fieldnorm(T, "col", 5, 50).unwrap();
67
68 let norm0 = idx.read_fieldnorm(T, "col", 0).unwrap().unwrap();
69 let norm5 = idx.read_fieldnorm(T, "col", 5).unwrap().unwrap();
70
71 assert!(norm0 <= 100);
72 assert!(norm5 <= 50);
73 assert_eq!(norm0, smallfloat::decode(smallfloat::encode(100)));
74 assert_eq!(norm5, smallfloat::decode(smallfloat::encode(50)));
75 }
76
77 #[test]
78 fn fieldnorm_missing_doc() {
79 let idx = FtsIndex::new(MemoryBackend::new());
80 assert_eq!(idx.read_fieldnorm(T, "col", 99).unwrap(), None);
81 }
82
83 #[test]
84 fn fieldnorm_overwrite() {
85 let idx = FtsIndex::new(MemoryBackend::new());
86 idx.write_fieldnorm(T, "col", 0, 100).unwrap();
87 idx.write_fieldnorm(T, "col", 0, 200).unwrap();
88
89 let norm = idx.read_fieldnorm(T, "col", 0).unwrap().unwrap();
90 assert_eq!(norm, smallfloat::decode(smallfloat::encode(200)));
91 }
92}