Branch data Line data Source code
1 : : /* flint_values.cc: Values in flint databases
2 : : *
3 : : * Copyright 1999,2000,2001 BrightStation PLC
4 : : * Copyright 2002 Ananova Ltd
5 : : * Copyright 2002,2003,2004,2005,2008 Olly Betts
6 : : *
7 : : * This program is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU General Public License as
9 : : * published by the Free Software Foundation; either version 2 of the
10 : : * License, or (at your option) any later version.
11 : : *
12 : : * This program is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : * GNU General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License
18 : : * along with this program; if not, write to the Free Software
19 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 : : * USA
21 : : */
22 : :
23 : : #include <config.h>
24 : : #include "flint_values.h"
25 : : #include "flint_utils.h"
26 : : #include "utils.h"
27 : : #include <xapian/error.h>
28 : : using std::string;
29 : : using std::make_pair;
30 : :
31 : : #include "debuglog.h"
32 : :
33 : : /** Generate key for document @a docid's values. */
34 : : inline void
35 : 352707 : make_key(string & key, Xapian::docid did)
36 : : {
37 : : LOGCALL_STATIC_VOID(DB, "make_key", key | did);
38 : 352707 : key = flint_docid_to_key(did);
39 : 352707 : }
40 : :
41 : : void
42 : 2188554 : FlintValueTable::unpack_entry(const char ** pos,
43 : : const char * end,
44 : : Xapian::valueno * this_value_no,
45 : : string & this_value)
46 : : {
47 : : LOGCALL_STATIC_VOID(DB, "FlintValueTable::unpack_entry", pos | (void*)end | this_value_no | this_value);
48 [ - + ]: 2188554 : if (!F_unpack_uint(pos, end, this_value_no)) {
49 [ # # ]: 0 : if (*pos == 0) throw Xapian::DatabaseCorruptError("Incomplete item in value table");
50 : 0 : else throw Xapian::RangeError("Value number in value table is too large");
51 : : }
52 : :
53 [ - + ]: 2188554 : if (!F_unpack_string(pos, end, this_value)) {
54 [ # # ]: 0 : if (*pos == 0) throw Xapian::DatabaseCorruptError("Incomplete item in value table");
55 : 0 : else throw Xapian::RangeError("Item in value table is too large");
56 : : }
57 : :
58 : : LOGLINE(DB, "FlintValueTable::unpack_entry(): value no " <<
59 : : this_value_no << " is `" << this_value << "'");
60 : 2188554 : }
61 : :
62 : : void
63 : 47490 : FlintValueTable::encode_values(string & s,
64 : : Xapian::ValueIterator it,
65 : : const Xapian::ValueIterator & end)
66 : : {
67 : : LOGCALL_VOID(DB, "FlintValueTable::encode_values", s | it | end);
68 [ + + ]: 305373 : while (it != end) {
69 : 257883 : s += F_pack_uint(it.get_valueno());
70 : 257883 : s += F_pack_string(*it);
71 : 257883 : ++it;
72 : : }
73 : 47490 : }
74 : :
75 : : void
76 : 47490 : FlintValueTable::set_encoded_values(Xapian::docid did, const string & enc)
77 : : {
78 : : LOGCALL_VOID(DB, "FlintValueTable::set_encoded_values", did | enc);
79 : 47490 : string key;
80 : 47490 : make_key(key, did);
81 : 47490 : add(key, enc);
82 : 47490 : }
83 : :
84 : : void
85 : 113676 : FlintValueTable::get_value(string & value,
86 : : Xapian::docid did,
87 : : Xapian::valueno valueno) const
88 : : {
89 : : LOGCALL_VOID(DB, "FlintValueTable::get_value", value | did | valueno);
90 : 113676 : string key;
91 : 113676 : make_key(key, did);
92 : 113676 : string tag;
93 : 113676 : bool found = get_exact_entry(key, tag);
94 : :
95 [ + + ]: 113676 : if (found) {
96 : 113664 : const char * pos = tag.data();
97 : 113664 : const char * end = pos + tag.size();
98 : :
99 [ + + + ]: 674128 : while (pos && pos != end) {
[ + - ][ + + ]
[ + + ]
100 : : Xapian::valueno this_value_no;
101 : 560464 : string this_value;
102 : :
103 : 560464 : unpack_entry(&pos, end, &this_value_no, this_value);
104 : :
105 [ + + ]: 560464 : if (this_value_no == valueno) {
106 : 103001 : value = this_value;
107 : : return;
108 : : }
109 : :
110 : : // Values are stored in sorted order.
111 [ + + ]: 457463 : if (this_value_no > valueno) break;
112 : : }
113 : : }
114 [ + + ]: 113676 : value = "";
115 : : }
116 : :
117 : : void
118 : 172473 : FlintValueTable::get_all_values(map<Xapian::valueno, string> & values,
119 : : Xapian::docid did) const
120 : : {
121 : : LOGCALL_VOID(DB, "FlintValueTable::get_all_values", values | did);
122 : 172473 : string key;
123 : 172473 : make_key(key, did);
124 : 172473 : string tag;
125 : 172473 : bool found = get_exact_entry(key, tag);
126 : :
127 : 172473 : values.clear();
128 [ - + ]: 172473 : if (!found) return;
129 : :
130 : 172473 : const char * pos = tag.data();
131 : 172473 : const char * end = pos + tag.size();
132 : :
133 [ + - ][ + + ]: 1800563 : while (pos && pos != end) {
[ + + ]
134 : : Xapian::valueno this_value_no;
135 : 1628090 : string this_value;
136 : :
137 : 1628090 : unpack_entry(&pos, end, &this_value_no, this_value);
138 : 1628090 : values.insert(make_pair(this_value_no, this_value));
139 [ - + ]: 172473 : }
140 : : }
141 : :
142 : : void
143 : 19068 : FlintValueTable::delete_all_values(Xapian::docid did)
144 : : {
145 : : LOGCALL_VOID(DB, "FlintValueTable::delete_all_values", did);
146 : 19068 : string key;
147 : 19068 : make_key(key, did);
148 : 19068 : del(key);
149 : 19068 : }
|