Index: ChangeLog
===================================================================
--- ChangeLog	(revision 8425)
+++ ChangeLog	(revision 8426)
@@ -1,3 +1,19 @@
+Thu May 03 00:05:23 BST 2007  Richard Boulton <richard@lemurconsulting.com>
+
+	* backends/flint/: Remove unused (and unimplemented) declarations
+	  of begin_transaction_(), commit_transaction_() and
+	  cancel_transaction_() from FlintWritableDatabase class.  Tidy up
+	  handling of metainfo (total_length and lastdocid) to avoid
+	  repeatedly parsing the special record, and make it easier to
+	  store additional metainfo in future.
+	  Also, remove code which ensures that there is always a special
+	  record - this was added in revision 5459 when the special record
+	  was stored in the record table, so that the number of documents
+	  in the database could always be calculated by subtracting 1 from
+	  the number of entries in the record table.  Now that the special
+	  record is stored in the postlist table, this is no longer
+	  necessary.
+
 Wed May 02 17:56:39 BST 2007  Olly Betts <olly@survex.com>
 
 	* backends/dbfactory_remote.cc,include/xapian/dbfactory.h:
Index: backends/flint/flint_database.h
===================================================================
--- backends/flint/flint_database.h	(revision 8425)
+++ backends/flint/flint_database.h	(revision 8426)
@@ -94,6 +94,14 @@
 	/// Lock object.
 	FlintLock lock;
 
+	/** Total length of all documents including unflushed modifications.
+	 */
+	flint_totlen_t total_length;
+
+	/** Highest document ID ever allocated by this database.
+	 */
+	Xapian::docid lastdocid;
+
 	/** Return true if a database exists at the path specified for this
 	 *  database.
 	 */
@@ -301,9 +309,6 @@
 	PositionList * open_position_list(Xapian::docid did,
 					  const string & tname) const;
 	TermList * open_allterms() const;
-	void begin_transaction_();
-	void commit_transaction_();
-	void cancel_transaction_();
 	//@}
 };
 
Index: backends/flint/flint_database.cc
===================================================================
--- backends/flint/flint_database.cc	(revision 8425)
+++ backends/flint/flint_database.cc	(revision 8426)
@@ -87,6 +87,7 @@
 	}
 	// Can still allow searches even if recovery is needed
 	open_tables_consistent();
+	postlist_table.get_metainfo_entry(total_length, lastdocid);
     } else {
 	if (!dbexists) {
 	    // FIXME: if we allow Xapian::DB_OVERWRITE, check it here
@@ -143,9 +144,7 @@
 	    value_table.commit(new_revision);
 	    record_table.commit(new_revision);
 	}
-	if (record_table.get_doccount() == 0) {
-	    postlist_table.set_total_length_and_lastdocid(0, postlist_table.get_lastdocid());
-	}
+	postlist_table.get_metainfo_entry(total_length, lastdocid);
     }
 }
 
@@ -196,7 +195,11 @@
 	revision != postlist_table.get_open_revision_number()) {
 	throw Xapian::DatabaseCreateError("Newly created tables are not in consistent state");
     }
-    postlist_table.set_total_length_and_lastdocid(0, 0);
+
+    // Set metainfo
+    total_length = 0;
+    lastdocid = 0;
+    postlist_table.set_metainfo_entry(total_length, lastdocid);
 }
 
 void
@@ -306,6 +309,7 @@
     DEBUGCALL(DB, void, "FlintDatabase::reopen", "");
     if (readonly) {
 	open_tables_consistent();
+	postlist_table.get_metainfo_entry(total_length, lastdocid);
     }
 }
 
@@ -392,7 +396,7 @@
 FlintDatabase::get_lastdocid() const
 {
     DEBUGCALL(DB, Xapian::docid, "FlintDatabase::get_lastdocid", "");
-    RETURN(postlist_table.get_lastdocid());
+    RETURN(lastdocid);
 }
 
 Xapian::doclength
@@ -401,7 +405,7 @@
     DEBUGCALL(DB, Xapian::doclength, "FlintDatabase::get_avlength", "");
     Xapian::doccount docs = record_table.get_doccount();
     if (docs == 0) RETURN(0);
-    RETURN(double(postlist_table.get_total_length()) / docs);
+    RETURN(double(total_length) / docs);
 }
 
 Xapian::doclength
@@ -532,12 +536,11 @@
 	  doclens(),
 	  mod_plists(),
 	  database_ro(dir, action, block_size),
-	  total_length(database_ro.postlist_table.get_total_length()),
-	  lastdocid(database_ro.get_lastdocid()),
 	  changes_made(0)
 {
     DEBUGCALL(DB, void, "FlintWritableDatabase", dir << ", " << action << ", "
 	      << block_size);
+    database_ro.postlist_table.get_metainfo_entry(total_length, lastdocid);
     if (flush_threshold == 0) {
 	const char *p = getenv("XAPIAN_FLUSH_THRESHOLD");
 	if (p) flush_threshold = atoi(p);
@@ -567,8 +570,7 @@
     database_ro.postlist_table.merge_changes(mod_plists, doclens, freq_deltas);
 
     // Update the total document length and last used docid.
-    database_ro.postlist_table.set_total_length_and_lastdocid(total_length,
-							      lastdocid);
+    database_ro.postlist_table.set_metainfo_entry(total_length, lastdocid);
     database_ro.apply();
     freq_deltas.clear();
     doclens.clear();
@@ -1070,8 +1072,7 @@
 FlintWritableDatabase::cancel()
 {
     database_ro.cancel();
-    total_length = database_ro.postlist_table.get_total_length();
-    lastdocid = database_ro.get_lastdocid();
+    database_ro.postlist_table.get_metainfo_entry(total_length, lastdocid);
     freq_deltas.clear();
     doclens.clear();
     mod_plists.clear();
Index: backends/flint/flint_postlist.cc
===================================================================
--- backends/flint/flint_postlist.cc	(revision 8425)
+++ backends/flint/flint_postlist.cc	(revision 8426)
@@ -30,55 +30,40 @@
 // next free docid and total length of all documents
 static const string METAINFO_KEY("", 1);
 
-Xapian::docid
-FlintPostListTable::get_lastdocid() const
+void
+FlintPostListTable::get_metainfo_entry(flint_totlen_t & totlen,
+				       Xapian::docid & did) const
 {
-    DEBUGCALL(DB, Xapian::docid, "FlintPostListTable::get_lastdocid", "");
+    DEBUGCALL(DB, void, "FlintPostListTable::get_metainfo_entry", "");
 
     string tag;
-    if (!get_exact_entry(METAINFO_KEY, tag)) RETURN(0u);
+    if (!get_exact_entry(METAINFO_KEY, tag)) {
+	totlen = 0;
+	did = 0;
+	return;
+    }
 
-    Xapian::docid did;
     const char * data = tag.data();
     const char * end = data + tag.size();
     if (!unpack_uint(&data, end, &did)) {
 	throw Xapian::DatabaseCorruptError("Record containing meta information is corrupt.");
     }
-    RETURN(did);
+    if (!unpack_uint_last(&data, end, &totlen)) {
+	throw Xapian::DatabaseCorruptError("Record containing meta information is corrupt.");
+    }
 }
 
 void
-FlintPostListTable::set_total_length_and_lastdocid(flint_totlen_t totlen,
-						  Xapian::docid did)
+FlintPostListTable::set_metainfo_entry(flint_totlen_t totlen,
+				       Xapian::docid did)
 {
-    DEBUGCALL(DB, void, "FlintPostListTable::set_total_length_and_lastdocid",
+    DEBUGCALL(DB, void, "FlintPostListTable::set_metainfo_entry",
 			totlen << ", " << did);
     string tag = pack_uint(did);
     tag += pack_uint_last(totlen);
     add(METAINFO_KEY, tag);
 }
 
-flint_totlen_t
-FlintPostListTable::get_total_length() const
-{
-    DEBUGCALL(DB, flint_totlen_t, "FlintPostListTable::get_total_length", "");
-
-    string tag;
-    if (!get_exact_entry(METAINFO_KEY, tag)) RETURN(0);
-
-    Xapian::docid did;
-    flint_totlen_t totlen;
-    const char * data = tag.data();
-    const char * end = data + tag.size();
-    if (!unpack_uint(&data, end, &did)) {
-	throw Xapian::DatabaseCorruptError("Record containing meta information is corrupt.");
-    }
-    if (!unpack_uint_last(&data, end, &totlen)) {
-	throw Xapian::DatabaseCorruptError("Record containing meta information is corrupt.");
-    }
-    RETURN(totlen);
-}
-
 /// Make a key for accessing the postlist.
 static void
 make_key(const string & tname, Xapian::docid did, string & key)
Index: backends/flint/flint_postlist.h
===================================================================
--- backends/flint/flint_postlist.h	(revision 8425)
+++ backends/flint/flint_postlist.h	(revision 8426)
@@ -67,18 +67,15 @@
 		Xapian::docid did, bool adding,
 		PostlistChunkReader ** from, PostlistChunkWriter **to);
 
-	/** Return the total length of all the records in the table.
+	/** Get the total length, last document ID used, and metadata.
 	 */
-	flint_totlen_t get_total_length() const;
+	void get_metainfo_entry(flint_totlen_t & totlen,
+				Xapian::docid & lastdocid) const;
 
-	/** Get the last document id used.
+	/** Set the total length, last document ID used, and metadata.
 	 */
-	Xapian::docid get_lastdocid() const;
-
-	/** Set the total length and last document ID used.
-	 */
-	void set_total_length_and_lastdocid(flint_totlen_t totlen,
-					    Xapian::docid did);
+	void set_metainfo_entry(flint_totlen_t totlen,
+				Xapian::docid lastdocid);
 };
 
 /** A postlist in a flint database.
