# # # patch "database.cc" # from [73e1ff5267346362c8e78501a242a695f715c105] # to [0ec57b6c928661ebf32258bb46847c95c5204924] # # patch "database.hh" # from [b64b02b9a2527a475360ad20edfefbe705220b87] # to [d3581237b7c45a5a5148584e89c987d39709369a] # ============================================================ --- database.cc 73e1ff5267346362c8e78501a242a695f715c105 +++ database.cc 0ec57b6c928661ebf32258bb46847c95c5204924 @@ -998,6 +998,7 @@ database::rollback_transaction() roster_cache.clear_and_drop_writes(); parent_to_child_map.reset(); child_to_parent_map.reset(); + height_cache.reset(); execute(query("ROLLBACK")); } transaction_level--; @@ -1924,6 +1925,7 @@ database::put_rev_height(revision_id con execute(query("INSERT INTO heights VALUES(?, ?)") % text(id.inner()()) % blob(height())); + } bool @@ -3268,41 +3270,64 @@ database::put_roster(revision_id const & guard.commit(); } +struct db_height_store : height_store +{ + db_height_store(database & db) : db(db) {} + virtual void get_height(revision_id const & rid, rev_height & height) const + { + map::const_iterator h = heights.find(rid); + if (h != heights.end()) + { + height = h->second; + } + else + { + db.get_rev_height(rid, height); + safe_insert(heights, make_pair(rid, height)); + } + } + + mutable database & db; + mutable map heights; +}; typedef boost::shared_ptr ancestry_map_p; +typedef boost::shared_ptr height_cache_p; void database::ensure_ancestry_maps_loaded() { - if (! (parent_to_child_map && child_to_parent_map)) + if (! (parent_to_child_map && child_to_parent_map && height_cache)) { + I( (!parent_to_child_map) && (!child_to_parent_map) && (!height_cache)); + results res; - - I( (!parent_to_child_map) && (!child_to_parent_map)); parent_to_child_map = ancestry_map_p(new ancestry_map); child_to_parent_map = ancestry_map_p(new ancestry_map); - + fetch(res, 2, any_rows, query("SELECT parent,child FROM revision_ancestry")); - + for (size_t i = 0; i < res.size(); ++i) { parent_to_child_map->insert(make_pair(res[i][0], res[i][1])); child_to_parent_map->insert(make_pair(res[i][1], res[i][0])); } + + height_cache = height_cache_p(new db_height_store(*this)); + height_cache->heights.clear(); + + fetch(res, 2, any_rows, + query("SELECT revision, height FROM heights")); + + for (size_t i = 0; i < res.size(); ++i) + { + safe_insert(height_cache->heights, make_pair(revision_id(res[i][0]), + rev_height(res[i][1]))); + } } } -struct db_height_store : height_store -{ - db_height_store(database & db) : db(db) {} - virtual void get_height(revision_id const & rid, rev_height & height) const - { - db.get_rev_height(rid, height); - } - - mutable database & db; -}; void database::get_uncommon_ancestors(revision_id const & a, @@ -3311,9 +3336,8 @@ database::get_uncommon_ancestors(revisio set & b_uncommon_ancs) { ensure_ancestry_maps_loaded(); - db_height_store heights(*this); // call the generic (and testable) function in graph.cc - ::get_uncommon_ancestors(a, b, *child_to_parent_map, heights, + ::get_uncommon_ancestors(a, b, *child_to_parent_map, *height_cache, a_uncommon_ancs, b_uncommon_ancs); } ============================================================ --- database.hh b64b02b9a2527a475360ad20edfefbe705220b87 +++ database.hh d3581237b7c45a5a5148584e89c987d39709369a @@ -76,6 +76,7 @@ class rev_height; struct revision_t; struct query; class rev_height; +struct db_height_store; class database { @@ -313,6 +314,8 @@ private: boost::shared_ptr > child_to_parent_map; + + boost::shared_ptr height_cache; void ensure_ancestry_maps_loaded();