Ticket #143: xapian-metadata.patch
File xapian-metadata.patch, 32.8 KB (added by , 18 years ago) |
---|
-
xapian-core/tests/api_wrdb.cc
1247 1247 return true; 1248 1248 } 1249 1249 1250 /** Test basic metadata access methods. */ 1251 static bool test_metadata1() 1252 { 1253 Xapian::WritableDatabase db = get_writable_database(""); 1254 1255 try { 1256 TEST_EXCEPTION(Xapian::MetadataNotFoundError, db.get_metadata("foo")); 1257 } catch (Xapian::UnimplementedError &e) { 1258 SKIP_TEST("Metadata not supported by this backend"); 1259 } 1260 db.set_metadata("foo", "bar"); 1261 TEST_EQUAL(db.get_metadata("foo"), "bar"); 1262 db.set_metadata("foo", "baz"); 1263 TEST_EQUAL(db.get_doccount(), 0); 1264 TEST_EQUAL(db.get_metadata("foo"), "baz"); 1265 db.delete_metadata("foo"); 1266 TEST_EXCEPTION(Xapian::MetadataNotFoundError, db.get_metadata("foo")); 1267 1268 TEST_EQUAL(db.get_doccount(), 0); 1269 1270 return true; 1271 } 1272 1273 /** Test the metadata gets applied at same time as transactions happen. */ 1274 static bool test_metadata2() 1275 { 1276 string path; 1277 const string & dbtype = get_dbtype(); 1278 if (dbtype == "flint") { 1279 path = ".flint/dbw"; 1280 } else { 1281 /* This test only works for backends which we can get a reader for as 1282 * well as a writer. */ 1283 SKIP_TEST("Test only supported for flint backend"); 1284 } 1285 Xapian::WritableDatabase db = get_writable_database(""); 1286 Xapian::Database dbr = Xapian::Database(path); 1287 1288 TEST_EXCEPTION(Xapian::MetadataNotFoundError, db.get_metadata("foo")); 1289 db.set_metadata("foo", "bar"); 1290 TEST_EQUAL(db.get_metadata("foo"), "bar"); 1291 TEST_EXCEPTION(Xapian::MetadataNotFoundError, dbr.get_metadata("foo")); 1292 db.flush(); 1293 TEST_EXCEPTION(Xapian::MetadataNotFoundError, dbr.get_metadata("foo")); 1294 dbr.reopen(); 1295 TEST_EQUAL(db.get_metadata("foo"), "bar"); 1296 TEST_EQUAL(dbr.get_metadata("foo"), "bar"); 1297 TEST_EQUAL(dbr.get_doccount(), 0); 1298 1299 db.add_document(Xapian::Document()); 1300 db.set_metadata("foo", "baz"); 1301 TEST_EQUAL(db.get_doccount(), 1); 1302 TEST_EQUAL(db.get_metadata("foo"), "baz"); 1303 db.flush(); 1304 1305 TEST_EQUAL(dbr.get_metadata("foo"), "bar"); 1306 dbr.reopen(); 1307 TEST_EQUAL(dbr.get_metadata("foo"), "baz"); 1308 1309 db.delete_metadata("foo"); 1310 TEST_EXCEPTION(Xapian::MetadataNotFoundError, db.get_metadata("foo")); 1311 db.flush(); 1312 TEST_EQUAL(dbr.get_metadata("foo"), "baz"); 1313 dbr.reopen(); 1314 TEST_EXCEPTION(Xapian::MetadataNotFoundError, dbr.get_metadata("foo")); 1315 1316 TEST_EQUAL(db.get_doccount(), 1); 1317 1318 return true; 1319 } 1320 1250 1321 // ####################################################################### 1251 1322 // # End of test cases: now we list the tests to run. 1252 1323 … … 1274 1345 {"allpostlist2", test_allpostlist2}, 1275 1346 {"consistency2", test_consistency2}, 1276 1347 {"crashrecovery1", test_crashrecovery1}, 1348 {"metadata1", test_metadata1}, 1349 {"metadata2", test_metadata2}, 1277 1350 {0, 0} 1278 1351 }; -
xapian-core/include/xapian/database.h
212 212 * could not be found in the database. 213 213 */ 214 214 Xapian::Document get_document(Xapian::docid did) const; 215 216 /** Get a piece of metadata associated with a given key. 217 * 218 * Metadata is used to hold information about the database as a whole, 219 * not about a specific term or document. 220 * 221 * This method returns a piece of user-specified metadata. 222 * 223 * If there is no piece of metadata stored with the given key, an 224 * exception will be thrown. 225 * 226 * @param key The key of the metadata item to access. May be the 227 * empty string. 228 * 229 * @return A string holding the retrieved metadata item. 230 * 231 * @exception Xapian::MetadataNotFoundError There was no metadata with the 232 * specified key in the database. 233 */ 234 std::string get_metadata(const std::string & key) const; 215 235 }; 216 236 217 237 /** This class provides read/write access to a database. … … 524 544 Xapian::docid replace_document(const std::string & unique_term, 525 545 const Xapian::Document & document); 526 546 547 /** Set a piece of metadata associated with a given key. 548 * 549 * Metadata is used to hold information about the database as a whole, 550 * not about a specific term or document. 551 * 552 * This sets the metadata value associated with a given key. If there 553 * is already a metadata value stored in the database with the same 554 * key, the old value is replaced. 555 * 556 * The modification is committed to disk in the same way as 557 * modifications to the documents in the database are: ie, 558 * modifications are atomic, and won't be committed to disk 559 * immediately; see flush() for more details. 560 * 561 * Because modifications to the metadata are included in transactions, 562 * metadata can be used to link databases with external resources 563 * which have version numbers, by storing the appropriate version 564 * number to link to the current content of the database in a metadata 565 * item. 566 * 567 * There may be limits on the size of metadata items, or the number of 568 * items stored, depending on the backend in use. Additionally, 569 * implementations are not currently optimised for storing large 570 * amounts of metadata. It is recommended that only a few small 571 * pieces of metadata, totalling no more than a few kilobytes, is 572 * stored in the metadata. If more information than this is needed, 573 * the metadata should be used to point to external resources holding 574 * the information. 575 * 576 * @param key The key of the metadata item to set. May be the 577 * empty string. There may be a limit on the length of 578 * the key imposed by the database backend in use (but 579 * anything up to 100 characters is likely to be fine). 580 * 581 * @param value The value of the metadata item to set. 582 * 583 * @exception Xapian::DatabaseError will be thrown if a problem occurs 584 * while writing to the database. 585 * 586 * @exception Xapian::DatabaseCorruptError will be thrown if the 587 * database is in a corrupt state. 588 */ 589 void set_metadata(const std::string & key, const std::string & value); 590 591 /** Delete a piece of metadata associated with a given key. 592 * 593 * If no piece of metadata is present in the database with the given 594 * key, no change is made, and no error is reported. 595 * 596 * @param key The key of the metadata item to remove. May be the 597 * empty string. 598 */ 599 void delete_metadata(const std::string & key); 600 527 601 /** Introspection method. 528 602 * 529 603 * @return A string describing this object. -
xapian-core/common/remote-database.h
157 157 /// Iterate all terms. 158 158 TermList * open_allterms() const; 159 159 160 std::string get_metadata(const std::string & key) const; 161 160 162 bool has_positions() const; 161 163 162 164 void reopen(); … … 202 204 void replace_document(Xapian::docid did, const Xapian::Document & doc); 203 205 Xapian::docid replace_document(const std::string & unique_term, 204 206 const Xapian::Document & document); 207 208 void set_metadata(const std::string & key, 209 const std::string & value); 210 void delete_metadata(const std::string & key); 205 211 }; 206 212 207 213 #endif // XAPIAN_INCLUDED_REMOTE_DATABASE_H -
xapian-core/common/database.h
236 236 virtual Xapian::Document::Internal * 237 237 open_document(Xapian::docid did, bool lazy = false) const = 0; 238 238 239 /** Get a piece of metadata associated with a given key. 240 * 241 * See Database::get_metadata() for more information. 242 */ 243 virtual std::string get_metadata(const std::string & key) const = 0; 244 239 245 /** Reopen the database to the latest available revision. 240 246 * 241 247 * Database backends which don't support simultaneous update and … … 306 312 virtual Xapian::docid replace_document(const std::string & unique_term, 307 313 const Xapian::Document & document); 308 314 315 /** Set a piece of metadata associated with a given key. 316 * 317 * See WritableDatabase::set_metadata() for more information. 318 */ 319 virtual void set_metadata(const std::string & key, const std::string & value); 320 321 /** Delete a piece of metadata associated with a given key. 322 * 323 * See WritableDatabase::delete_metadata() for more information. 324 */ 325 virtual void delete_metadata(const std::string & key); 326 309 327 /** Request and later collect a document from the database. 310 328 * Multiple documents can be requested with request_document(), 311 329 * and then collected with collect_document(). Allows the backend -
xapian-core/exception_data.pm
132 132 /** Indicates an attempt to access a document not present in the database. */ 133 133 DOC 134 134 135 errorclass('MetadataNotFoundError', 'RuntimeError', <<'DOC'); 136 /** Indicates an attempt to access a metadata key not present in the database. */ 137 DOC 138 135 139 errorclass('FeatureUnavailableError', 'RuntimeError', <<'DOC'); 136 140 /** Indicates an attempt to use a feature which is unavailable. 137 141 * -
xapian-core/api/omdatabase.cc
301 301 RETURN(Document(internal[n]->open_document(m))); 302 302 } 303 303 304 std::string 305 Database::get_metadata(const std::string & key) const 306 { 307 DEBUGAPICALL(void, "Database::get_metadata", key); 308 return internal[0]->get_metadata(key); 309 } 310 304 311 bool 305 312 Database::term_exists(const string & tname) const 306 313 { … … 434 441 return internal[0]->replace_document(unique_term, document); 435 442 } 436 443 444 void 445 WritableDatabase::set_metadata(const std::string & key, 446 const std::string & value) 447 { 448 DEBUGAPICALL(void, "WritableDatabase::set_metadata", 449 key << ", " << value); 450 internal[0]->set_metadata(key, value); 451 } 452 453 void 454 WritableDatabase::delete_metadata(const std::string & key) 455 { 456 DEBUGAPICALL(void, "WritableDatabase::delete_metadata", key); 457 internal[0]->delete_metadata(key); 458 } 459 437 460 string 438 461 WritableDatabase::get_description() const 439 462 { -
xapian-core/backends/inmemory/inmemory_database.cc
712 712 return new InMemoryAllTermsList(&postlists, 713 713 Xapian::Internal::RefCntPtr<const InMemoryDatabase>(this)); 714 714 } 715 716 void 717 InMemoryDatabase::set_metadata(const std::string & key, 718 const std::string & value) 719 { 720 metadata[key] = value; 721 } 722 723 void 724 InMemoryDatabase::delete_metadata(const std::string & key) 725 { 726 metadata.erase(key); 727 } 728 729 std::string 730 InMemoryDatabase::get_metadata(const std::string & key) const 731 { 732 map<string, string>::const_iterator i = metadata.find(key); 733 if (i == metadata.end()) 734 throw Xapian::MetadataNotFoundError(string("Metadata key `") + key + "` not found."); 735 return i->second; 736 } -
xapian-core/backends/inmemory/inmemory_database.h
234 234 235 235 vector<Xapian::doclength> doclengths; 236 236 237 std::map<string, string> metadata; 238 237 239 Xapian::doccount totdocs; 238 240 239 241 Xapian::doclength totlen; … … 278 280 #endif 279 281 void delete_document(Xapian::docid did); 280 282 void replace_document(Xapian::docid did, const Xapian::Document & document); 283 void set_metadata(const std::string & key, 284 const std::string & value); 285 void delete_metadata(const std::string & key); 281 286 //@} 282 287 283 288 public: … … 307 312 PositionList * open_position_list(Xapian::docid did, 308 313 const string & tname) const; 309 314 TermList * open_allterms() const; 315 std::string get_metadata(const std::string & key) const; 310 316 }; 311 317 312 318 #endif /* OM_HGUARD_INMEMORY_DATABASE_H */ -
xapian-core/backends/quartz/quartz_database.h
216 216 PositionList * open_position_list(Xapian::docid did, 217 217 const string & tname) const; 218 218 TermList * open_allterms() const; 219 std::string get_metadata(const std::string & key) const; 219 220 //@} 220 221 }; 221 222 … … 277 278 virtual void delete_document(Xapian::docid did); 278 279 virtual void replace_document(Xapian::docid did, 279 280 const Xapian::Document & document); 281 virtual void set_metadata(const std::string & key, 282 const std::string & value); 283 virtual void delete_metadata(const std::string & key); 280 284 //@} 281 285 282 286 public: … … 308 312 PositionList * open_position_list(Xapian::docid did, 309 313 const string & tname) const; 310 314 TermList * open_allterms() const; 315 std::string get_metadata(const std::string & key) const; 311 316 //@} 312 317 }; 313 318 -
xapian-core/backends/quartz/quartz_database.cc
667 667 pl_cursor, postlist_table.get_entry_count())); 668 668 } 669 669 670 std::string 671 QuartzDatabase::get_metadata(const std::string &) const 672 { 673 throw Xapian::UnimplementedError("Metadata not implemented for Quartz databases."); 674 } 675 670 676 size_t QuartzWritableDatabase::flush_threshold = 0; 671 677 672 678 QuartzWritableDatabase::QuartzWritableDatabase(const string &dir, int action, … … 1046 1052 do_flush_const(); 1047 1053 } 1048 1054 1055 void 1056 QuartzWritableDatabase::set_metadata(const std::string &, 1057 const std::string &) 1058 { 1059 throw Xapian::UnimplementedError("Metadata not implemented for Quartz databases."); 1060 } 1061 1062 void 1063 QuartzWritableDatabase::delete_metadata(const std::string &) 1064 { 1065 throw Xapian::UnimplementedError("Metadata not implemented for Quartz databases."); 1066 } 1067 1049 1068 Xapian::doccount 1050 1069 QuartzWritableDatabase::get_doccount() const 1051 1070 { … … 1204 1223 pl_cursor, t->get_entry_count())); 1205 1224 } 1206 1225 1226 std::string 1227 QuartzWritableDatabase::get_metadata(const std::string &) const 1228 { 1229 throw Xapian::UnimplementedError("Metadata not implemented for Quartz databases."); 1230 } 1231 1207 1232 void 1208 1233 QuartzWritableDatabase::cancel() 1209 1234 { -
xapian-core/backends/database.cc
360 360 return did; 361 361 } 362 362 363 void 364 Database::Internal::set_metadata(const std::string &, const std::string &) 365 { 366 // Writable databases should override this method. 367 Assert(false); 363 368 } 369 370 void 371 Database::Internal::delete_metadata(const std::string &) 372 { 373 // Writable databases should override this method. 374 Assert(false); 375 } 376 377 } -
xapian-core/backends/remote/remote-database.cc
555 555 const char * p_end = p + message.size(); 556 556 return decode_length(&p, p_end, false); 557 557 } 558 559 std::string 560 RemoteDatabase::get_metadata(const std::string &) const 561 { 562 throw Xapian::UnimplementedError("Metadata not implemented for Remote databases."); 563 } 564 565 void 566 RemoteDatabase::set_metadata(const std::string &, 567 const std::string &) 568 { 569 throw Xapian::UnimplementedError("Metadata not implemented for Remote databases."); 570 } 571 572 void 573 RemoteDatabase::delete_metadata(const std::string &) 574 { 575 throw Xapian::UnimplementedError("Metadata not implemented for Remote databases."); 576 } -
xapian-core/backends/flint/Makefile.mk
14 14 backends/flint/flint_document.h\ 15 15 backends/flint/flint_io.h\ 16 16 backends/flint/flint_lock.h\ 17 backends/flint/flint_metadata.h\ 17 18 backends/flint/flint_modifiedpostlist.h\ 18 19 backends/flint/flint_positionlist.h\ 19 20 backends/flint/flint_postlist.h\ … … 34 35 backends/flint/flint_document.cc\ 35 36 backends/flint/flint_io.cc\ 36 37 backends/flint/flint_lock.cc\ 38 backends/flint/flint_metadata.cc\ 37 39 backends/flint/flint_modifiedpostlist.cc\ 38 40 backends/flint/flint_positionlist.cc\ 39 41 backends/flint/flint_postlist.cc\ -
xapian-core/backends/flint/flint_database.h
24 24 #define OM_HGUARD_FLINT_DATABASE_H 25 25 26 26 #include "database.h" 27 #include "flint_metadata.h" 27 28 #include "flint_positionlist.h" 28 29 #include "flint_postlist.h" 29 30 #include "flint_record.h" … … 102 103 */ 103 104 Xapian::docid lastdocid; 104 105 106 /** The metadata for this database. 107 */ 108 FlintMetadata metadata; 109 105 110 /** Return true if a database exists at the path specified for this 106 111 * database. 107 112 */ … … 217 222 PositionList * open_position_list(Xapian::docid did, 218 223 const string & tname) const; 219 224 TermList * open_allterms() const; 225 string get_metadata(const string & key) const; 220 226 //@} 221 227 }; 222 228 … … 247 253 */ 248 254 mutable Xapian::docid lastdocid; 249 255 256 /** The metadata for this database. 257 */ 258 FlintMetadata metadata; 259 260 /** Flag, true iff the metadata has been modified. 261 */ 262 mutable bool metadata_modified; 263 250 264 /** The number of documents added, deleted, or replaced since the last 251 265 * flush. 252 266 */ … … 278 292 virtual void delete_document(Xapian::docid did); 279 293 virtual void replace_document(Xapian::docid did, 280 294 const Xapian::Document & document); 295 virtual void set_metadata(const string & key, 296 const string & value); 297 virtual void delete_metadata(const string & key); 281 298 //@} 282 299 283 300 public: … … 309 326 PositionList * open_position_list(Xapian::docid did, 310 327 const string & tname) const; 311 328 TermList * open_allterms() const; 329 string get_metadata(const string & key) const; 312 330 //@} 313 331 }; 314 332 -
xapian-core/backends/flint/flint_metadata.h
1 /* flint_metadata.h: Metadata in flint databases 2 * 3 * Copyright 2007 Lemur Consulting Ltd 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 18 * USA 19 */ 20 21 #ifndef XAPIAN_INCLUDED_FLINT_METADATA_H 22 #define XAPIAN_INCLUDED_FLINT_METADATA_H 23 24 #include <map> 25 #include <string> 26 #include <xapian/error.h> 27 28 using namespace std; 29 30 /** Class holding the metadata for a flint database. 31 * 32 * This class also 33 */ 34 class FlintMetadata { 35 private: 36 /** The serialised form of the metadata. */ 37 mutable string serialised; 38 39 /** Parsed form of the metadata. */ 40 mutable map<string, string> lookup; 41 42 /** Flag, true iff the serialised form is up-to-date. */ 43 mutable bool serialised_uptodate; 44 45 /** Flag, true iff the parsed form in `lookup` is up-to-date. */ 46 mutable bool parsed; 47 48 /** Parse the serialised metadata. 49 * 50 * "lookup" is populated with the results. 51 */ 52 void parse() const; 53 54 /** Serialise the serialised metadata. 55 * 56 * "serialised" to set to contain the information in "lookup". 57 */ 58 void unparse() const; 59 60 public: 61 /** Create a new metadata object. 62 * 63 * @param serialised_ - Serialised form of the metadata. 64 */ 65 FlintMetadata() 66 : serialised(), 67 serialised_uptodate(true), 68 parsed(false) 69 {} 70 71 /** Get the metadata item with the given key. 72 */ 73 const string & get(const string & key) const 74 { 75 if (!parsed) parse(); 76 map<string, string>::const_iterator i = lookup.find(key); 77 if (i == lookup.end()) 78 throw Xapian::MetadataNotFoundError(string("Metadata key `") + key + "` not found."); 79 return i->second; 80 } 81 82 /** Set the metadata item with the given key. 83 */ 84 void set(const string & key, const string & value) 85 { 86 if (!parsed) parse(); 87 lookup[key] = value; 88 serialised_uptodate = false; 89 } 90 91 /** Delete the metadata item with the given key. 92 */ 93 void del(const string & key) 94 { 95 if (!parsed) parse(); 96 lookup.erase(key); 97 serialised_uptodate = false; 98 } 99 100 void clear() 101 { 102 serialised.clear(); 103 serialised_uptodate = true; 104 parsed = false; 105 } 106 107 /** Serialise the metadata. 108 */ 109 const string & serialise() const 110 { 111 if (!serialised_uptodate) unparse(); 112 return serialised; 113 } 114 115 /** Set the metadata from a serialised form. 116 */ 117 void unserialise(string serialised_) 118 { 119 serialised = serialised_; 120 serialised_uptodate = true; 121 parsed = false; 122 } 123 }; 124 125 #endif /* XAPIAN_INCLUDED_FLINT_METADATA_H */ -
xapian-core/backends/flint/flint_version.cc
Property changes on: xapian-core/backends/flint/flint_metadata.h ___________________________________________________________________ Name: svn:eol-style + native
36 36 using std::string; 37 37 38 38 // YYYYMMDDX where X allows multiple format revisions in a day 39 #define FLINT_VERSION 200704230u 39 #define FLINT_VERSION 200705040u 40 // 200705040 Support user-specified metadata 40 41 // 200704230 Use zlib compression of tags for record and termlist tables 41 42 // 200611200 Fixed occasional, architecture-dependent surplus bits in 42 43 // interpolative coding; "flicklock" -> "flintlock". -
xapian-core/backends/flint/flint_database.cc
87 87 } 88 88 // Can still allow searches even if recovery is needed 89 89 open_tables_consistent(); 90 postlist_table.get_metainfo_entry(total_length, lastdocid );90 postlist_table.get_metainfo_entry(total_length, lastdocid, metadata); 91 91 } else { 92 92 if (!dbexists) { 93 93 // FIXME: if we allow Xapian::DB_OVERWRITE, check it here … … 144 144 value_table.commit(new_revision); 145 145 record_table.commit(new_revision); 146 146 } 147 postlist_table.get_metainfo_entry(total_length, lastdocid );147 postlist_table.get_metainfo_entry(total_length, lastdocid, metadata); 148 148 } 149 149 } 150 150 … … 199 199 // Set metainfo 200 200 total_length = 0; 201 201 lastdocid = 0; 202 postlist_table.set_metainfo_entry(total_length, lastdocid); 202 metadata.clear(); 203 postlist_table.set_metainfo_entry(total_length, lastdocid, metadata); 203 204 } 204 205 205 206 void … … 309 310 DEBUGCALL(DB, void, "FlintDatabase::reopen", ""); 310 311 if (readonly) { 311 312 open_tables_consistent(); 312 postlist_table.get_metainfo_entry(total_length, lastdocid );313 postlist_table.get_metainfo_entry(total_length, lastdocid, metadata); 313 314 } 314 315 } 315 316 … … 528 529 &postlist_table)); 529 530 } 530 531 532 string 533 FlintDatabase::get_metadata(const string & key) const 534 { 535 DEBUGCALL(DB, string, "FlintDatabase::get_metadata", key); 536 RETURN(metadata.get(key)); 537 } 538 531 539 size_t FlintWritableDatabase::flush_threshold = 0; 532 540 533 541 FlintWritableDatabase::FlintWritableDatabase(const string &dir, int action, … … 536 544 doclens(), 537 545 mod_plists(), 538 546 database_ro(dir, action, block_size), 547 metadata_modified(false), 539 548 changes_made(0) 540 549 { 541 550 DEBUGCALL(DB, void, "FlintWritableDatabase", dir << ", " << action << ", " 542 551 << block_size); 543 database_ro.postlist_table.get_metainfo_entry(total_length, lastdocid); 552 database_ro.postlist_table.get_metainfo_entry(total_length, lastdocid, 553 metadata); 544 554 if (flush_threshold == 0) { 545 555 const char *p = getenv("XAPIAN_FLUSH_THRESHOLD"); 546 556 if (p) flush_threshold = atoi(p); … … 559 569 { 560 570 if (transaction_active()) 561 571 throw Xapian::InvalidOperationError("Can't flush during a transaction"); 562 if (changes_made ) do_flush_const();572 if (changes_made || metadata_modified) do_flush_const(); 563 573 } 564 574 565 575 void … … 570 580 database_ro.postlist_table.merge_changes(mod_plists, doclens, freq_deltas); 571 581 572 582 // Update the total document length and last used docid. 573 database_ro.postlist_table.set_metainfo_entry(total_length, lastdocid); 583 database_ro.postlist_table.set_metainfo_entry(total_length, lastdocid, 584 metadata); 585 metadata_modified = false; 574 586 database_ro.apply(); 575 587 freq_deltas.clear(); 576 588 doclens.clear(); … … 1069 1081 } 1070 1082 1071 1083 void 1084 FlintWritableDatabase::set_metadata(const std::string & key, 1085 const std::string & value) 1086 { 1087 DEBUGCALL(DB, string, "FlintWritableDatabase::set_metadata", key << ", " << value); 1088 metadata.set(key, value); 1089 metadata_modified = true; 1090 } 1091 1092 void 1093 FlintWritableDatabase::delete_metadata(const std::string & key) 1094 { 1095 DEBUGCALL(DB, string, "FlintWritableDatabase::delete_metadata", key); 1096 metadata.del(key); 1097 metadata_modified = true; 1098 } 1099 1100 string 1101 FlintWritableDatabase::get_metadata(const string & key) const 1102 { 1103 DEBUGCALL(DB, string, "FlintWritableDatabase::get_metadata", key); 1104 RETURN(metadata.get(key)); 1105 } 1106 1107 void 1072 1108 FlintWritableDatabase::cancel() 1073 1109 { 1074 1110 database_ro.cancel(); 1075 database_ro.postlist_table.get_metainfo_entry(total_length, lastdocid); 1111 database_ro.postlist_table.get_metainfo_entry(total_length, lastdocid, 1112 metadata); 1113 metadata_modified = false; 1076 1114 freq_deltas.clear(); 1077 1115 doclens.clear(); 1078 1116 mod_plists.clear(); -
xapian-core/backends/flint/flint_metadata.cc
1 /* flint_metadata.cc: Metadata in flint databases 2 * 3 * Copyright 2007 Lemur Consulting Ltd 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 * USA 19 */ 20 21 #include <config.h> 22 #include "flint_metadata.h" 23 #include "flint_utils.h" 24 #include <xapian/error.h> 25 #include "omdebug.h" 26 27 void 28 FlintMetadata::parse() const 29 { 30 DEBUGCALL(DB, void, "FlintMetadata::parse", ""); 31 const char * pos = serialised.data(); 32 const char * end = pos + serialised.size(); 33 lookup.clear(); 34 map<string, string>::iterator i = lookup.begin(); 35 36 while (pos != end) { 37 string key; 38 string value; 39 if (!unpack_string(&pos, end, key)) 40 throw Xapian::DatabaseCorruptError("Couldn't read key from metadata"); 41 if (pos == end) 42 throw Xapian::DatabaseCorruptError("Couldn't read length of value from metadata"); 43 if (!unpack_string(&pos, end, value)) 44 throw Xapian::DatabaseCorruptError("Couldn't read value from metadata"); 45 i = lookup.insert(i, make_pair(key, value)); 46 } 47 48 parsed = true; 49 } 50 51 void 52 FlintMetadata::unparse() const 53 { 54 DEBUGCALL(DB, void, "FlintMetadata::unparse", ""); 55 serialised.clear(); 56 57 map<string, string>::const_iterator i; 58 for (i = lookup.begin(); i != lookup.end(); ++i) 59 { 60 serialised.append(pack_string(i->first)); 61 serialised.append(pack_string(i->second)); 62 } 63 serialised_uptodate = true; 64 } -
xapian-core/backends/flint/flint_postlist.cc
Property changes on: xapian-core/backends/flint/flint_metadata.cc ___________________________________________________________________ Name: svn:eol-style + native
22 22 #include <config.h> 23 23 #include "omdebug.h" 24 24 #include "flint_postlist.h" 25 #include "flint_metadata.h" 25 26 #include "flint_utils.h" 26 27 #include "flint_cursor.h" 27 28 #include "database.h" 28 29 29 30 // Magic key (which corresponds to an invalid docid) is used to store the 30 // next free docid and total length of all documents31 // next free docid, total length of all documents, and the database metadata. 31 32 static const string METAINFO_KEY("", 1); 32 33 33 34 void 34 35 FlintPostListTable::get_metainfo_entry(flint_totlen_t & totlen, 35 Xapian::docid & did) const 36 Xapian::docid & did, 37 FlintMetadata & metadata) const 36 38 { 37 39 DEBUGCALL(DB, void, "FlintPostListTable::get_metainfo_entry", ""); 38 40 … … 40 42 if (!get_exact_entry(METAINFO_KEY, tag)) { 41 43 totlen = 0; 42 44 did = 0; 45 metadata.clear(); 43 46 return; 44 47 } 45 48 … … 48 51 if (!unpack_uint(&data, end, &did)) { 49 52 throw Xapian::DatabaseCorruptError("Record containing meta information is corrupt."); 50 53 } 51 if (!unpack_uint _last(&data, end, &totlen)) {54 if (!unpack_uint(&data, end, &totlen)) { 52 55 throw Xapian::DatabaseCorruptError("Record containing meta information is corrupt."); 53 56 } 57 metadata.unserialise(string(data, end)); 54 58 } 55 59 56 60 void 57 61 FlintPostListTable::set_metainfo_entry(flint_totlen_t totlen, 58 Xapian::docid did) 62 Xapian::docid did, 63 const FlintMetadata & metadata) 59 64 { 60 65 DEBUGCALL(DB, void, "FlintPostListTable::set_metainfo_entry", 61 totlen << ", " << did );66 totlen << ", " << did << ", " << metadata.serialise()); 62 67 string tag = pack_uint(did); 63 tag += pack_uint_last(totlen); 68 tag += pack_uint(totlen); 69 tag += metadata.serialise(); 64 70 add(METAINFO_KEY, tag); 65 71 } 66 72 -
xapian-core/backends/flint/flint_postlist.h
35 35 using namespace std; 36 36 37 37 class FlintCursor; 38 class Flint Database;38 class FlintMetadata; 39 39 40 40 class PostlistChunkReader; 41 41 class PostlistChunkWriter; … … 70 70 /** Get the total length, last document ID used, and metadata. 71 71 */ 72 72 void get_metainfo_entry(flint_totlen_t & totlen, 73 Xapian::docid & lastdocid) const; 73 Xapian::docid & lastdocid, 74 FlintMetadata & metadata) const; 74 75 75 76 /** Set the total length, last document ID used, and metadata. 76 77 */ 77 78 void set_metainfo_entry(flint_totlen_t totlen, 78 Xapian::docid lastdocid); 79 Xapian::docid lastdocid, 80 const FlintMetadata & metadata); 79 81 }; 80 82 81 83 /** A postlist in a flint database. -
xapian-bindings/xapian.i
666 666 doclength get_doclength(docid docid) const; 667 667 void keep_alive(); 668 668 Document get_document(docid did); 669 std::string get_metadata(const std::string & key) const; 669 670 }; 670 671 671 672 class WritableDatabase : public Database { … … 687 688 void delete_document(const std::string & unique_term); 688 689 Xapian::docid replace_document(const std::string & unique_term, 689 690 const Xapian::Document & document); 691 void set_metadata(const std::string & key, const std::string & value); 692 void delete_metadata(const std::string & key); 690 693 691 694 string get_description() const; 692 695 };