summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Masurel <paul.masurel@gmail.com>2017-06-13 23:16:42 +0900
committerPaul Masurel <paul.masurel@gmail.com>2017-06-13 23:16:50 +0900
commit8875b9794acddd19e828a981ec99bb27e0b57a0d (patch)
tree60eae6b515570353361a115efa6d3a39ae064ee1
parent90fcfb3f43da1bcf105ac15b2dcdf3167ff9b8c2 (diff)
Added API to get range from fastfield
-rw-r--r--src/common/bitpacker.rs24
-rw-r--r--src/fastfield/reader.rs22
2 files changed, 46 insertions, 0 deletions
diff --git a/src/common/bitpacker.rs b/src/common/bitpacker.rs
index 6aa1f5d..5df1e72 100644
--- a/src/common/bitpacker.rs
+++ b/src/common/bitpacker.rs
@@ -127,6 +127,30 @@ impl<Data> BitUnpacker<Data>
let val_shifted = (val_unshifted_unmasked >> bit_shift) as u64;
(val_shifted & mask)
}
+
+ pub fn get_range(&self, start: u32, output: &mut [u64]) {
+ if self.num_bits == 0 {
+ for val in output.iter_mut() {
+ *val = 0;
+ }
+ }
+ else {
+ let data: &[u8] = &*self.data;
+ let num_bits = self.num_bits;
+ let mask = self.mask;
+
+ let mut addr_in_bits = (start as usize) * num_bits;
+ for i in 0..output.len() {
+ let addr = addr_in_bits >> 3;
+ let bit_shift = addr_in_bits & 7;
+ let val_unshifted_unmasked: u64 = unsafe { *(data[addr..].as_ptr() as *const u64) };
+ let val_shifted = (val_unshifted_unmasked >> bit_shift) as u64;
+ output[i] = val_shifted & mask;
+ addr_in_bits += num_bits;
+ }
+ }
+
+ }
}
diff --git a/src/fastfield/reader.rs b/src/fastfield/reader.rs
index 7c01d0a..8413527 100644
--- a/src/fastfield/reader.rs
+++ b/src/fastfield/reader.rs
@@ -13,6 +13,7 @@ use common::bitpacker::compute_num_bits;
use common::bitpacker::BitUnpacker;
use schema::FieldType;
use error::ResultExt;
+use std::mem;
use common;
use owning_ref::OwningRef;
@@ -29,6 +30,7 @@ pub trait FastFieldReader: Sized {
/// This accessor should return as fast as possible.
fn get(&self, doc: DocId) -> Self::ValueType;
+ fn get_range(&self, start: u32, output: &mut [Self::ValueType]);
/// Opens a fast field given a source.
fn open(source: ReadOnlySource) -> Self;
@@ -80,6 +82,13 @@ impl FastFieldReader for U64FastFieldReader {
}
}
+ fn get_range(&self, start: u32, output: &mut [Self::ValueType]) {
+ self.bit_unpacker.get_range(start, output);
+ for out in output.iter_mut() {
+ *out += self.min_value;
+ }
+ }
+
/// Opens a new fast field reader given a read only source.
///
/// # Panics
@@ -181,6 +190,19 @@ impl FastFieldReader for I64FastFieldReader {
common::u64_to_i64(self.underlying.get(doc))
}
+ ///
+ /// # Panics
+ ///
+ /// May panic or return wrong random result if `doc`
+ /// is greater or equal to the segment's `maxdoc`.
+ fn get_range(&self, start: u32, output: &mut [Self::ValueType]) {
+ let output_u64: &mut [u64] = unsafe { mem::transmute(output) };
+ self.underlying.get_range(start, output_u64);
+ for mut_val in output_u64.iter_mut() {
+ *mut_val ^= 1 << 63;
+ }
+ }
+
/// Opens a new fast field reader given a read only source.
///
/// # Panics