# # # patch "ChangeLog" # from [b6b72c9ba5a8bc4a1667c4c15599995625714e4b] # to [3b0faf979ea7bb1aee21366128eb7f77cbb29f58] # # patch "database.cc" # from [1a02f5ffde18b3350f69282aa05ac52e90e87f90] # to [984427d1b818696b6d6ca34b15d9825d315662d7] # # patch "database.hh" # from [41d2dc5966c177a9f31f51bfb28cedabb1c07136] # to [9bd0680ba679954f3dd24abe2f95245458c5c321] # ============================================================ --- ChangeLog b6b72c9ba5a8bc4a1667c4c15599995625714e4b +++ ChangeLog 3b0faf979ea7bb1aee21366128eb7f77cbb29f58 @@ -1,3 +1,16 @@ +2006-05-07 Graydon Hoare + + * database.{cc,hh} (pending_writes): New fulltext write buffer, + gives about 20% performance gain on initial pull. + (database::have_pending_write): Helper function. + (database::load_pending_write): Likewise. + (database::cancel_pending_write): Likewise. + (database::schedule_write): Likewise. + (database::exists): Modify to use buffer. + (database::put_version): Likewise. + (database::put_file): Likewise. + (database::put_roster): Likewise. + 2006-05-06 Lapo Luchini * po/it.po: Translated a few more strings to Italian (162 to go). ============================================================ --- database.cc 1a02f5ffde18b3350f69282aa05ac52e90e87f90 +++ database.cc 984427d1b818696b6d6ca34b15d9825d315662d7 @@ -30,6 +30,7 @@ #include "database.hh" #include "hash_map.hh" #include "keys.hh" +#include "safe_map.hh" #include "sanity.hh" #include "schema_migration.hh" #include "transforms.hh" @@ -801,11 +802,47 @@ transaction_level++; } + +bool +database::have_pending_write(string const & tab, hexenc const & id) +{ + return pending_writes.find(make_pair(tab, id)) != pending_writes.end(); +} + void +database::load_pending_write(string const & tab, hexenc const & id, data & dat) +{ + dat = safe_get(pending_writes, make_pair(tab, id)); +} + +void +database::cancel_pending_write(string const & tab, hexenc const & id) +{ + safe_erase(pending_writes, make_pair(tab, id)); +} + +void +database::schedule_write(string const & tab, + hexenc const & id, + data const & dat) +{ + if (!have_pending_write(tab, id)) + safe_insert(pending_writes, make_pair(make_pair(tab, id), dat)); +} + +void database::commit_transaction() { if (transaction_level == 1) - execute(query("COMMIT")); + { + for (map >, data>::const_iterator i = pending_writes.begin(); + i != pending_writes.end(); ++i) + { + put(i->first.second, i->second, i->first.first); + } + pending_writes.clear(); + execute(query("COMMIT")); + } transaction_level--; } @@ -822,6 +859,9 @@ database::exists(hexenc const & ident, string const & table) { + if (have_pending_write(table, ident)) + return true; + results res; query q("SELECT id FROM " + table + " WHERE id = ?"); fetch(res, one_col, any_rows, q % text(ident())); @@ -899,6 +939,12 @@ data & dat, string const & table) { + if (have_pending_write(table, ident)) + { + load_pending_write(table, ident, dat); + return; + } + results res; query q("SELECT data FROM " + table + " WHERE id = ?"); fetch(res, one_col, one_row, q % text(ident())); @@ -1208,9 +1254,12 @@ { // descendent of a head version replaces the head, therefore old head // must be disposed of - drop(old_id, data_table); + if (have_pending_write(data_table, old_id)) + cancel_pending_write(data_table, old_id); + else + drop(old_id, data_table); } - put(new_id, new_data, data_table); + schedule_write(data_table, new_id, new_data); put_delta(old_id, new_id, reverse_delta, delta_table); guard.commit(); } @@ -1414,7 +1463,7 @@ database::put_file(file_id const & id, file_data const & dat) { - put(id.inner(), dat.inner(), "files"); + schedule_write("files", id.inner(), dat.inner()); } void @@ -2780,7 +2829,7 @@ // Else we have a new roster the database hasn't seen yet; our task is to // add it, and deltify all the incoming edges (if they aren't already). - put(new_id, new_data, data_table); + schedule_write(data_table, new_id, new_data); std::set parents; get_revision_parents(rev_id, parents); @@ -2798,7 +2847,10 @@ { get_version(old_id, old_data, data_table, delta_table); diff(new_data, old_data, reverse_delta); - drop(old_id, data_table); + if (have_pending_write(data_table, old_id)) + cancel_pending_write(data_table, old_id); + else + drop(old_id, data_table); put_delta(old_id, new_id, reverse_delta, delta_table); } } ============================================================ --- database.hh 41d2dc5966c177a9f31f51bfb28cedabb1c07136 +++ database.hh 9bd0680ba679954f3dd24abe2f95245458c5c321 @@ -87,7 +87,13 @@ }; std::map statement_cache; + std::map >, data> pending_writes; + bool have_pending_write(std::string const & tab, hexenc const & id); + void load_pending_write(std::string const & tab, hexenc const & id, data & dat); + void cancel_pending_write(std::string const & tab, hexenc const & id); + void schedule_write(std::string const & tab, hexenc const & id, data const & dat); + struct app_state * __app; struct sqlite3 * __sql; struct sqlite3 * sql(bool init = false, bool migrating_format = false);