Ticket #508: xapian-orpositionlist.patch
File xapian-orpositionlist.patch, 8.5 KB (added by , 8 years ago) |
---|
-
xapian-core/matcher/Makefile.mk
diff --git a/xapian-core/matcher/Makefile.mk b/xapian-core/matcher/Makefile.mk index 2e1a4b9d..6a0aa722 100644
a b noinst_HEADERS +=\ 16 16 matcher/multimatch.h\ 17 17 matcher/multixorpostlist.h\ 18 18 matcher/nearpostlist.h\ 19 matcher/orpositionlist.h\ 19 20 matcher/orpostlist.h\ 20 21 matcher/phrasepostlist.h\ 21 22 matcher/queryoptimiser.h\ … … lib_src +=\ 54 55 matcher/multimatch.cc\ 55 56 matcher/multixorpostlist.cc\ 56 57 matcher/nearpostlist.cc\ 58 matcher/orpositionlist.cc\ 57 59 matcher/orpostlist.cc\ 58 60 matcher/phrasepostlist.cc\ 59 61 matcher/selectpostlist.cc\ -
new file xapian-core/matcher/orpositionlist.cc
diff --git a/xapian-core/matcher/orpositionlist.cc b/xapian-core/matcher/orpositionlist.cc new file mode 100644 index 00000000..acbb787a
- + 1 /** @file orpositionlist.cc 2 * @brief Merge two PositionList objects using an OR operation. 3 */ 4 /* Copyright (C) 2007,2010,2016 Olly Betts 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <config.h> 22 23 #include "orpositionlist.h" 24 25 #include "debuglog.h" 26 #include "omassert.h" 27 28 using namespace std; 29 30 Xapian::termcount 31 OrPositionList::get_size() const 32 { 33 LOGCALL(EXPAND, Xapian::termcount, "OrPositionList::get_size", NO_ARGS); 34 // This is actually the upper bound, but generally there's only one term 35 // at each position, so it'll usually be correct too. 36 RETURN(left->get_size() + right->get_size()); 37 } 38 39 Xapian::termpos 40 OrPositionList::get_position() const 41 { 42 LOGCALL(EXPAND, Xapian::termpos, "OrPositionList::get_position", NO_ARGS); 43 if (left_current < right_current) RETURN(left_current); 44 RETURN(right_current); 45 } 46 47 void 48 OrPositionList::next() 49 { 50 LOGCALL_VOID(EXPAND, "OrPositionList::next", NO_ARGS); 51 // If we've not started yet, both left_current and right_current will be 0, 52 // which gets handled by calling next() on both, which is what we want to 53 // do to get started. 54 if (left_current <= right_current) { 55 bool equal = (left_current == right_current); 56 if (equal && left_current == Xapian::termpos(-1)) { 57 // Both either at_end() or on the largest value and will be 58 // at_end() if we call next(). 59 left = right = NULL; 60 return; 61 } 62 63 left->next(); 64 if (left->at_end()) { 65 left_current = Xapian::termpos(-1); 66 left = NULL; 67 } else { 68 left_current = left->get_position(); 69 } 70 if (!equal) return; 71 } 72 73 right->next(); 74 if (right->at_end()) { 75 right_current = Xapian::termpos(-1); 76 right = NULL; 77 } else { 78 right_current = right->get_position(); 79 } 80 } 81 82 void 83 OrPositionList::skip_to(Xapian::termpos termpos) 84 { 85 LOGCALL_VOID(EXPAND, "OrPositionList::skip_to", termpos); 86 // If we've not started yet, both left_current and right_current will be 0, 87 // which gets handled by calling next() on both, which is what we want to 88 // do to get started. 89 if (left_current <= right_current) { 90 bool equal = (left_current == right_current); 91 if (equal && left_current == Xapian::termpos(-1)) { 92 // Both either at_end() or on the largest value, so skip_to() is a 93 // no-op. 94 return; 95 } 96 97 left->skip_to(termpos); 98 if (left->at_end()) { 99 left_current = Xapian::termpos(-1); 100 left = NULL; 101 } else { 102 left_current = left->get_position(); 103 } 104 if (!equal) return; 105 } 106 107 right->skip_to(termpos); 108 if (right->at_end()) { 109 right_current = Xapian::termpos(-1); 110 right = NULL; 111 } else { 112 right_current = right->get_position(); 113 } 114 } 115 116 bool 117 OrPositionList::at_end() const 118 { 119 LOGCALL(EXPAND, bool, "OrPositionList::at_end", NO_ARGS); 120 RETURN(left == NULL && right == NULL); 121 } -
new file xapian-core/matcher/orpositionlist.h
diff --git a/xapian-core/matcher/orpositionlist.h b/xapian-core/matcher/orpositionlist.h new file mode 100644 index 00000000..6b271673
- + 1 /** @file orpositionlist.h 2 * @brief Merge two PositionList objects using an OR operation. 3 */ 4 /* Copyright (C) 2007,2010 Olly Betts 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef XAPIAN_INCLUDED_ORPOSITIONLIST_H 22 #define XAPIAN_INCLUDED_ORPOSITIONLIST_H 23 24 #include "backends/positionlist.h" 25 26 class OrPositionList : public PositionList { 27 protected: 28 /// The two PositionList objects we're merging. 29 PositionList *left, *right; 30 31 /// The current position for left and right respectively. 32 Xapian::termpos left_current, right_current; 33 34 public: 35 OrPositionList() { } 36 37 void init(PositionList * left_, PositionList * right_) { 38 left = left_; 39 right = right_; 40 left_current = 0; 41 right_current = 0; 42 } 43 44 Xapian::termcount get_size() const; 45 46 Xapian::termpos get_position() const; 47 48 void next(); 49 50 void skip_to(Xapian::termpos termpos); 51 52 bool at_end() const; 53 }; 54 55 #endif // XAPIAN_INCLUDED_ORPOSITIONLIST_H -
xapian-core/matcher/orpostlist.cc
diff --git a/xapian-core/matcher/orpostlist.cc b/xapian-core/matcher/orpostlist.cc index 88c65fe3..2613b09f 100644
a b 2 2 * 3 3 * Copyright 1999,2000,2001 BrightStation PLC 4 4 * Copyright 2001,2002 Ananova Ltd 5 * Copyright 2003,2004,2007,2008,2009,2010,2011,2012 Olly Betts5 * Copyright 2003,2004,2007,2008,2009,2010,2011,2012,2016 Olly Betts 6 6 * Copyright 2009 Lemur Consulting Ltd 7 7 * Copyright 2010 Richard Boulton 8 8 * … … 30 30 #include "andmaybepostlist.h" 31 31 #include "omassert.h" 32 32 33 #include "orpositionlist.h" 34 33 35 #include <algorithm> 34 36 35 37 OrPostList::OrPostList(PostList *left_, … … OrPostList::recalc_maxweight() 370 372 RETURN(OrPostList::get_maxweight()); 371 373 } 372 374 375 PositionList * 376 OrPostList::read_position_list() 377 { 378 if (lhead < rhead) return l->read_position_list(); 379 if (lhead > rhead) return r->read_position_list(); 380 position_list.init(l->read_position_list(), r->read_position_list()); 381 return &position_list; 382 } 383 373 384 bool 374 385 OrPostList::at_end() const 375 386 { -
xapian-core/matcher/orpostlist.h
diff --git a/xapian-core/matcher/orpostlist.h b/xapian-core/matcher/orpostlist.h index bde56c9a..86c542fd 100644
a b 3 3 */ 4 4 /* Copyright 1999,2000,2001 BrightStation PLC 5 5 * Copyright 2002 Ananova Ltd 6 * Copyright 2003,2004,2009,2010,2011 Olly Betts6 * Copyright 2003,2004,2009,2010,2011,2016 Olly Betts 7 7 * Copyright 2009 Lemur Consulting Ltd 8 8 * Copyright 2010 Richard Boulton 9 9 * … … 27 27 #define OM_HGUARD_ORPOSTLIST_H 28 28 29 29 #include "branchpostlist.h" 30 #include "orpositionlist.h" 30 31 31 32 /** A postlist comprising two postlists ORed together. 32 33 * … … class OrPostList : public BranchPostList { 41 42 bool lvalid, rvalid; 42 43 double lmax, rmax, minmax; 43 44 Xapian::doccount dbsize; 45 // FIXME: Do we want an OrWithPosPostList so we don't have the overhead 46 // of an OrPositionList object on every OrPostList. 47 OrPositionList position_list; 44 48 public: 45 49 Xapian::doccount get_termfreq_max() const; 46 50 Xapian::doccount get_termfreq_min() const; … … class OrPostList : public BranchPostList { 54 58 55 59 double recalc_maxweight(); 56 60 61 PositionList * read_position_list(); 62 57 63 PostList *next(double w_min); 58 64 PostList *skip_to(Xapian::docid did, double w_min); 59 65 PostList *check(Xapian::docid did, double w_min, bool &valid);