From e3dafcdf8b43880c6a1e0451c8ee621f7c3cb954 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 16 Jan 2013 16:31:29 +0200 Subject: Make session cache management functions static, add notifications --- odb/cache-traits.hxx | 78 ++++++++++++++++++++------------------- odb/database.txx | 4 +- odb/no-op-cache-traits.hxx | 35 ++++++++++++++---- odb/polymorphic-object-result.txx | 2 +- odb/session.cxx | 29 ++++++--------- odb/session.hxx | 46 +++++++++++++++++------ odb/session.ixx | 3 +- odb/session.txx | 26 +++++++++---- odb/simple-object-result.txx | 4 +- 9 files changed, 138 insertions(+), 89 deletions(-) diff --git a/odb/cache-traits.hxx b/odb/cache-traits.hxx index 5732cfc..5ab5022 100644 --- a/odb/cache-traits.hxx +++ b/odb/cache-traits.hxx @@ -28,29 +28,19 @@ namespace odb typedef odb::pointer_traits pointer_traits; typedef typename pointer_traits::element_type object_type; typedef typename object_traits::id_type id_type; - - struct position_type - { - typedef typename session_type::template position base_type; - - position_type (): empty_ (true) {} - position_type (const base_type& pos): empty_ (false), pos_ (pos) {} - - bool empty_; - base_type pos_; - }; + typedef typename session_type::template position position_type; struct insert_guard { insert_guard () {} insert_guard (const position_type& pos): pos_ (pos) {} - ~insert_guard () {erase (pos_);} + ~insert_guard () {session_type::erase (pos_);} const position_type& position () const {return pos_;} void - release () {pos_.empty_ = true;} + release () {pos_ = position_type ();} // Note: doesn't call erase() on the old position (assumes empty). // @@ -61,6 +51,8 @@ namespace odb position_type pos_; }; + // Cache management. + // // We need the insert() overload with explicit id to handle self- // references. In such cases the object is not yet loaded and the // id member does not contain the correct id. @@ -70,18 +62,7 @@ namespace odb static position_type insert (odb::database& db, const id_type& id, const pointer_type& p) { - if (session_type::has_current ()) - return session_type::current ().template insert ( - db, id, p); - else - return position_type (); - } - - static void - initialize (const position_type& p) - { - if (!p.empty_) - session_type::template initialize (p.pos_); + return session_type::template insert (db, id, p); } static position_type @@ -91,30 +72,45 @@ namespace odb object_traits::id ( pointer_traits::get_ref (p))); - return insert (db, id, p); + return session_type::template insert (db, id, p); } static pointer_type find (odb::database& db, const id_type& id) { - if (session_type::has_current ()) - return session_type::current ().template find (db, id); - else - return pointer_type (); + return session_type::template find (db, id); } static void - erase (odb::database& db, const id_type& id) + erase (const position_type& p) { - if (session_type::has_current ()) - session_type::current ().template erase (db, id); + session_type::template erase (p); } + // Notifications. + // static void - erase (const position_type& p) + persist (const position_type& p) { - if (!p.empty_) - session_type::template erase (p.pos_); + session_type::template persist (p); + } + + static void + load (const position_type& p) + { + session_type::template load (p); + } + + static void + update (odb::database& db, const object_type& obj) + { + session_type::template update (db, obj); + } + + static void + erase (odb::database& db, const id_type& id) + { + session_type::template erase (db, id); } }; @@ -163,9 +159,15 @@ namespace odb } static void - initialize (const position_type& p) + persist (const position_type& p) + { + pointer_traits::persist (p); + } + + static void + load (const position_type& p) { - pointer_traits::initialize (p); + pointer_traits::load (p); } }; diff --git a/odb/database.txx b/odb/database.txx index b5f9640..d96fd14 100644 --- a/odb/database.txx +++ b/odb/database.txx @@ -40,7 +40,7 @@ namespace odb object_traits::reference_cache_traits::insert ( *this, reference_cache_type::convert (obj))); - object_traits::reference_cache_traits::initialize (p); + object_traits::reference_cache_traits::persist (p); return object_traits::id (obj); } @@ -65,7 +65,7 @@ namespace odb object_traits::pointer_cache_traits::insert ( *this, pointer_cache_type::convert (pobj))); - object_traits::pointer_cache_traits::initialize (p); + object_traits::pointer_cache_traits::persist (p); return object_traits::id (obj); } diff --git a/odb/no-op-cache-traits.hxx b/odb/no-op-cache-traits.hxx index 5600a81..f1bf718 100644 --- a/odb/no-op-cache-traits.hxx +++ b/odb/no-op-cache-traits.hxx @@ -114,6 +114,8 @@ namespace odb reset (const position_type&) {} }; + // Cache management. + // static position_type insert (odb::database&, const id_type&, const pointer_type&) { @@ -128,17 +130,25 @@ namespace odb static position_type insert (odb::database&, void*) {return position_type ();} - static void - initialize (const position_type&) {} - static pointer_type find (odb::database&, const id_type&) {return pointer_type ();} static void - erase (odb::database&, const id_type&) {} + erase (const position_type&) {} + // Notifications. + // static void - erase (const position_type&) {} + persist (const position_type&) {} + + static void + load (const position_type&) {} + + static void + update (odb::database&, const object_type&) {} + + static void + erase (odb::database&, const id_type&) {} }; template @@ -156,7 +166,10 @@ namespace odb insert (odb::database&, void*) {return position_type ();} static void - initialize (const position_type&) {} + persist (const position_type&) {} + + static void + load (const position_type&) {} }; // reference_cache_traits @@ -196,7 +209,10 @@ namespace odb insert (odb::database&, object_type&) {return position_type ();} static void - initialize (const position_type&) {} + persist (const position_type&) {} + + static void + load (const position_type&) {} }; template @@ -209,7 +225,10 @@ namespace odb insert (odb::database&, object_type&) {return position_type ();} static void - initialize (const position_type&) {} + persist (const position_type&) {} + + static void + load (const position_type&) {} }; } diff --git a/odb/polymorphic-object-result.txx b/odb/polymorphic-object-result.txx index 69d365d..7ee2b82 100644 --- a/odb/polymorphic-object-result.txx +++ b/odb/polymorphic-object-result.txx @@ -65,7 +65,7 @@ namespace odb res_->db_, res_->load_id (), obj)); typename object_traits::reference_cache_traits::insert_guard ig (p); res_->load (&obj, false); - object_traits::reference_cache_traits::initialize (p); + object_traits::reference_cache_traits::load (p); ig.release (); } } diff --git a/odb/session.cxx b/odb/session.cxx index 3ca6af4..0f18684 100644 --- a/odb/session.cxx +++ b/odb/session.cxx @@ -21,7 +21,7 @@ namespace odb if (has_current ()) throw already_in_session (); - current (*this); + current_pointer (this); } } @@ -30,14 +30,20 @@ namespace odb { // If we are the current thread's session, reset it. // - if (has_current () && ¤t () == this) + if (current_pointer () == this) reset_current (); } - bool session:: - has_current () + session* session:: + current_pointer () { - return tls_get (current_session) != 0; + return tls_get (current_session); + } + + void session:: + current_pointer (session* s) + { + tls_set (current_session, s); } session& session:: @@ -51,19 +57,6 @@ namespace odb return *cur; } - void session:: - current (session& s) - { - tls_set (current_session, &s); - } - - void session:: - reset_current () - { - session* s (0); - tls_set (current_session, s); - } - // // object_map_base // diff --git a/odb/session.hxx b/odb/session.hxx index 3f58a80..6c9359c 100644 --- a/odb/session.hxx +++ b/odb/session.hxx @@ -42,7 +42,7 @@ namespace odb // thread. // static bool - has_current (); + has_current () {return current_pointer () != 0;} // Get current thread's session. Throw if no session is in effect. // @@ -52,12 +52,18 @@ namespace odb // Set current thread's session. // static void - current (session&); + current (session& s) {current_pointer (&s);} // Revert to the no session in effect state for the current thread. // static void - reset_current (); + reset_current () {current_pointer (0);} + + static session* + current_pointer (); + + static void + current_pointer (session*); // Copying or assignment of sessions is not supported. // @@ -84,7 +90,8 @@ namespace odb public: // Position in the cache of an inserted element. The requirements // for this class template are: default and copy-constructible as - // well as copy-assignable. + // well as copy-assignable. The default constructor creates an + // empty/NULL position. // template struct position @@ -92,35 +99,50 @@ namespace odb typedef object_map map; typedef typename map::iterator iterator; - position () {} + position (): map_ (0) {} position (map& m, const iterator& p): map_ (&m), pos_ (p) {} map* map_; iterator pos_; }; + // The following cache management functions are all static to + // allow for a custom notion of a current session. The erase() + // function is called to remove the object if the operation + // that caused it to be inserted (e.g., load) failed. + // template - position + static position insert (database_type&, const typename object_traits::id_type&, const typename object_traits::pointer_type&); template + static typename object_traits::pointer_type + find (database_type&, const typename object_traits::id_type&); + + template static void - initialize (const position&) {} + erase (const position&); + // Notifications. These are called after per-object callbacks for + // post_{persist, load, update, erase} events. + // template - typename object_traits::pointer_type - find (database_type&, const typename object_traits::id_type&) const; + static void + persist (const position&) {} template - void - erase (database_type&, const typename object_traits::id_type&); + static void + load (const position&) {} template static void - erase (const position&); + update (database_type&, const T&) {} + template + static void + erase (database_type&, const typename object_traits::id_type&); // Low-level object cache access (iteration, etc). // diff --git a/odb/session.ixx b/odb/session.ixx index 50a2ca1..4748cae 100644 --- a/odb/session.ixx +++ b/odb/session.ixx @@ -12,6 +12,7 @@ namespace odb { // @@ Empty maps are not cleaned up by this version of erase. // - p.map_->erase (p.pos_); + if (p.map_ != 0) + p.map_->erase (p.pos_); } } diff --git a/odb/session.txx b/odb/session.txx index 941f059..e89e439 100644 --- a/odb/session.txx +++ b/odb/session.txx @@ -12,7 +12,11 @@ namespace odb { typedef odb::object_traits object_traits; - type_map& tm (db_map_[&db]); + session* s (current_pointer ()); + if (s == 0) + return position (); + + type_map& tm (s->db_map_[&db]); details::shared_ptr& pom (tm[&typeid (T)]); if (!pom) @@ -36,13 +40,17 @@ namespace odb template typename object_traits::pointer_type session:: - find (database_type& db, const typename object_traits::id_type& id) const + find (database_type& db, const typename object_traits::id_type& id) { typedef typename object_traits::pointer_type pointer_type; - database_map::const_iterator di (db_map_.find (&db)); + const session* s (current_pointer ()); + if (s == 0) + return pointer_type (); + + database_map::const_iterator di (s->db_map_.find (&db)); - if (di == db_map_.end ()) + if (di == s->db_map_.end ()) return pointer_type (); const type_map& tm (di->second); @@ -64,9 +72,13 @@ namespace odb void session:: erase (database_type& db, const typename object_traits::id_type& id) { - database_map::iterator di (db_map_.find (&db)); + session* s (current_pointer ()); + if (s == 0) + return; + + database_map::iterator di (s->db_map_.find (&db)); - if (di == db_map_.end ()) + if (di == s->db_map_.end ()) return; type_map& tm (di->second); @@ -87,6 +99,6 @@ namespace odb tm.erase (ti); if (tm.empty ()) - db_map_.erase (di); + s->db_map_.erase (di); } } diff --git a/odb/simple-object-result.txx b/odb/simple-object-result.txx index f14caac..1a6332c 100644 --- a/odb/simple-object-result.txx +++ b/odb/simple-object-result.txx @@ -30,7 +30,7 @@ namespace odb object_type& obj (pointer_traits::get_ref (p)); current (p); load (obj, false); - object_traits::pointer_cache_traits::initialize (ig.position ()); + object_traits::pointer_cache_traits::load (ig.position ()); ig.release (); } } @@ -53,7 +53,7 @@ namespace odb res_->db_, res_->load_id (), obj)); typename object_traits::reference_cache_traits::insert_guard ig (p); res_->load (obj, false); - object_traits::reference_cache_traits::initialize (p); + object_traits::reference_cache_traits::load (p); ig.release (); } } -- cgit v1.1