Lighter HeapItem by putting term freq aside, and keeping ord as u32

This commit is contained in:
Paul Masurel
2016-08-03 11:29:15 +09:00
parent a05d414011
commit 4acc6f673d
2 changed files with 23 additions and 24 deletions
+20 -19
View File
@@ -6,17 +6,10 @@ use query::MultiTermScorer;
use postings::ScoredDocSet;
use query::Scorer;
use fastfield::U32FastFieldReader;
use std::iter;
#[derive(Eq, PartialEq)]
struct HeapItem(DocId, usize, u32);
impl HeapItem {
pub fn ord(&self,) -> usize{
self.1
}
}
struct HeapItem(DocId, u32);
impl PartialOrd for HeapItem {
fn partial_cmp(&self, other:&Self) -> Option<Ordering> {
@@ -26,13 +19,14 @@ impl PartialOrd for HeapItem {
impl Ord for HeapItem {
fn cmp(&self, other:&Self) -> Ordering {
(self.0, self.1).cmp(&(other.0, other.1)).reverse()
(other.0).cmp(&self.0)
}
}
pub struct UnionPostings<TPostings: Postings> {
fieldnorms_readers: Vec<U32FastFieldReader>,
postings: Vec<TPostings>,
term_frequencies: Vec<u32>,
queue: BinaryHeap<HeapItem>,
doc: DocId,
scorer: MultiTermScorer
@@ -43,23 +37,27 @@ impl<TPostings: Postings> UnionPostings<TPostings> {
pub fn new(fieldnorms_reader: Vec<U32FastFieldReader>, mut postings: Vec<TPostings>, multi_term_scorer: MultiTermScorer) -> UnionPostings<TPostings> {
let num_postings = postings.len();
assert_eq!(fieldnorms_reader.len(), num_postings);
for posting in &mut postings {
assert!(posting.next());
}
let heap_items: Vec<HeapItem> = postings.iter()
let mut term_frequencies: Vec<u32> = iter::repeat(0u32).take(num_postings).collect();
let heap_items: Vec<HeapItem> = postings
.iter()
.map(|posting| {
(posting.doc(), posting.term_freq())
})
.enumerate()
.map(|(ord, (doc, tf))| {
HeapItem(doc, ord, tf)
term_frequencies[ord] = tf;
HeapItem(doc, ord as u32)
})
.collect();
UnionPostings {
fieldnorms_readers: fieldnorms_reader,
postings: postings,
term_frequencies: term_frequencies,
queue: BinaryHeap::from(heap_items),
doc: 0,
scorer: multi_term_scorer
@@ -67,17 +65,16 @@ impl<TPostings: Postings> UnionPostings<TPostings> {
}
fn advance_head(&mut self,) {
let ord = self.queue.peek().unwrap().ord();
let ord = self.queue.peek().unwrap().1 as usize;
let cur_postings = &mut self.postings[ord];
if cur_postings.next() {
let doc = cur_postings.doc();
let tf = cur_postings.term_freq();
self.queue.replace(HeapItem(doc, ord, tf));
self.term_frequencies[ord] = cur_postings.term_freq();
self.queue.replace(HeapItem(doc, ord as u32));
}
else {
self.queue.pop();
}
}
fn get_field_norm(&self, ord:usize, doc:DocId) -> u32 {
@@ -93,9 +90,11 @@ impl<TPostings: Postings> DocSet for UnionPostings<TPostings> {
self.scorer.clear();
let cur_doc: DocId;
match self.queue.peek() {
Some(&HeapItem(doc, ord, tf)) => {
Some(&HeapItem(doc, ord)) => {
cur_doc = doc;
let ord: usize = ord as usize;
let fieldnorm = self.get_field_norm(ord, doc);
let tf = self.term_frequencies[ord];
self.scorer.update(ord, tf, fieldnorm);
}
@@ -106,11 +105,13 @@ impl<TPostings: Postings> DocSet for UnionPostings<TPostings> {
self.advance_head();
loop {
match self.queue.peek() {
Some(&HeapItem(peek_doc, peek_ord, peek_tf)) => {
Some(&HeapItem(peek_doc, peek_ord)) => {
if peek_doc != cur_doc {
break;
}
else {
let peek_ord: usize = peek_ord as usize;
let peek_tf = self.term_frequencies[peek_ord];
let fieldnorm = self.get_field_norm(peek_ord, peek_doc);
self.scorer.update(peek_ord, peek_tf, fieldnorm);
}
+3 -5
View File
@@ -20,11 +20,9 @@ impl MultiTermScorer {
}
pub fn update(&mut self, term_ord: usize, term_freq: u32, fieldnorm: u32) {
if term_freq > 0 {
self.score += (term_freq as f32 / fieldnorm as f32).sqrt() * self.idf[term_ord];
// self.score += term_freq as f32; // / fieldnorm as f32).sqrt() * self.idf[term_ord];
self.num_fields += 1;
}
assert!(term_freq != 0u32);
self.score += (term_freq as f32 / fieldnorm as f32).sqrt() * self.idf[term_ord];
self.num_fields += 1;
}
fn coord(&self,) -> f32 {