1 /** @file honey_postlisttable.cc
2 * @brief Subclass of HoneyTable which holds postlists.
4 /* Copyright (C) 2007,2008,2009,2010,2013,2014,2015,2016,2017 Olly Betts
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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.
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
23 #include "honey_postlisttable.h"
25 #include "honey_cursor.h"
26 #include "honey_database.h"
27 #include "honey_postlist.h"
28 #include "honey_postlist_encodings.h"
35 HoneyPostListTable::open_post_list(const HoneyDatabase
* db
,
36 const std::string
& term
,
39 Assert(!term
.empty());
40 // Try to position cursor first so we avoid creating HoneyPostList objects
41 // for terms which don't exist.
42 unique_ptr
<HoneyCursor
> cursor(cursor_get());
43 if (!cursor
->find_exact(Honey::make_postingchunk_key(term
))) {
44 // FIXME: Return NULL here and handle that in Query::Internal
45 // postlist() methods as we build the PostList tree.
47 return new HoneyPostList(db
, term
, NULL
);
51 return new HoneyPosPostList(db
, term
, cursor
.release());
52 return new HoneyPostList(db
, term
, cursor
.release());
56 HoneyPostListTable::get_freqs(const std::string
& term
,
57 Xapian::doccount
* termfreq_ptr
,
58 Xapian::termcount
* collfreq_ptr
) const
61 if (!get_exact_entry(Honey::make_postingchunk_key(term
), chunk
)) {
62 if (termfreq_ptr
) *termfreq_ptr
= 0;
63 if (collfreq_ptr
) *collfreq_ptr
= 0;
67 const char* p
= chunk
.data();
68 const char* pend
= p
+ chunk
.size();
71 if (!decode_initial_chunk_header_freqs(&p
, pend
, tf
, cf
))
72 throw Xapian::DatabaseCorruptError("Postlist initial chunk header");
73 if (termfreq_ptr
) *termfreq_ptr
= tf
;
74 if (collfreq_ptr
) *collfreq_ptr
= cf
;
78 HoneyPostListTable::get_used_docid_range(Xapian::docid
& first
,
79 Xapian::docid
& last
) const
81 unique_ptr
<HoneyCursor
> cursor
;
82 if (cursor
->find_entry_ge(string("\0\xe0", 2))) {
85 // doccount == 0 should be handled by our caller.
86 Assert(!cursor
->after_end());
87 const char* p
= cursor
->current_key
.data();
88 const char* pend
= p
+ cursor
->current_key
.size();
92 !unpack_uint_preserving_sort(&p
, pend
, &first
) ||
94 // Note that our caller checks for doccount == 0 and handles that.
95 throw Xapian::DatabaseCorruptError("Bad first doclen chunk");
99 cursor
->find_entry_lt(string("\0\xe1", 2));
101 if (cursor
->current_key
.size() == 2) {
102 // Must be a single doclen chunk starting at 1.
103 AssertEq(cursor
->current_key
[0], '\0');
104 AssertEq(cursor
->current_key
[1], '\xe0');
105 last
= cursor
->current_tag
.size() >> 2;
107 const char* p
= cursor
->current_key
.data();
108 const char* pend
= p
+ cursor
->current_key
.size();
112 !unpack_uint_preserving_sort(&p
, pend
, &last
) ||
114 throw Xapian::DatabaseCorruptError("Bad final doclen chunk");
116 last
+= (cursor
->current_tag
.size() >> 2) - 1;