From 12aa1b18d99b51e513e9e82c0ed45717d7538ca0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 28 Sep 2013 10:51:12 +0200 Subject: Make schema version access (but not modification) thread-safe Also cache the version in statements so that we don't have to lock the mutex (slow) every time we need to check the version. --- odb/relational/inline.hxx | 6 -- odb/relational/source.cxx | 190 ++++++++++++++++++++++++---------------------- odb/relational/source.hxx | 8 +- 3 files changed, 105 insertions(+), 99 deletions(-) diff --git a/odb/relational/inline.hxx b/odb/relational/inline.hxx index 95b4328..d1a4393 100644 --- a/odb/relational/inline.hxx +++ b/odb/relational/inline.hxx @@ -235,12 +235,6 @@ namespace relational bool versioned (context::versioned (c)); - // Schema name as a string literal or empty. - // - string schema_name (options.schema_name ()[db]); - if (!schema_name.empty ()) - schema_name = strlit (schema_name); - string const& type (class_fq_name (c)); string traits ("access::object_traits_impl< " + type + ", id_" + db.string () + " >"); diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx index 366120c..b12bce3 100644 --- a/odb/relational/source.cxx +++ b/odb/relational/source.cxx @@ -1150,19 +1150,20 @@ traverse_object (type& c) << "throw abstract_class ();" << endl; + os << db << "::connection& conn (" << endl + << db << "::transaction::current ().connection ());" + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object ());"; + if (versioned || persist_versioned_containers || uss.count (user_sections::count_new | user_sections::count_all | user_sections::count_versioned_only) != 0) os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; + "sts.version_migration (" << schema_name << "));"; - os << db << "::connection& conn (" << endl - << db << "::transaction::current ().connection ());" - << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object ());" - << endl; + os << endl; // Call callback (pre_persist). // @@ -1502,12 +1503,24 @@ traverse_object (type& c) << endl; } + bool sts (false); + if ((versioned && update_columns) || update_versioned_containers || versioned_sections) + { + sts = true; + os << db << "::transaction& tr (" << db << + "::transaction::current ());" + << db << "::connection& conn (tr.connection ());" + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object ());" + << endl; + os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));" + "sts.version_migration (" << schema_name << "));" << endl; + } // If we have change-updated sections that contain change-tracking // containers, then mark such sections as changed if any of the @@ -1587,10 +1600,10 @@ traverse_object (type& c) { bool readonly_base (context::readonly (*poly_base)); - if (readonly_base || - update_columns || - update_containers || - sections) + if (!sts && (readonly_base || + update_columns || + update_containers || + sections)) { os << db << "::transaction& tr (" << db << "::transaction::current ());" @@ -1685,12 +1698,13 @@ traverse_object (type& c) } else if (update_columns) { - os << db << "::transaction& tr (" << db << - "::transaction::current ());" - << db << "::connection& conn (tr.connection ());" - << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object ());" - << endl; + if (!sts) + os << db << "::transaction& tr (" << db << + "::transaction::current ());" + << db << "::connection& conn (tr.connection ());" + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object ());" + << endl; // Initialize id image. // @@ -1800,12 +1814,13 @@ traverse_object (type& c) // to initialize the id image if we are polymorphic or have // any containers or sections. // - os << db << "::transaction& tr (" << db << - "::transaction::current ());" - << db << "::connection& conn (tr.connection ());" - << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object ());" - << endl; + if (!sts) + os << db << "::transaction& tr (" << db << + "::transaction::current ());" + << db << "::connection& conn (tr.connection ());" + << "statements_type& sts (" << endl + << "conn.statement_cache ().find_object ());" + << endl; // The same rationale as a couple of screens up. // @@ -2155,7 +2170,7 @@ traverse_object (type& c) if (erase_versioned_containers) os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; + "sts.version_migration (" << schema_name << "));"; os << endl; @@ -2313,7 +2328,7 @@ traverse_object (type& c) if (erase_versioned_containers) os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; + "sts.version_migration (" << schema_name << "));"; os << endl; @@ -2409,7 +2424,7 @@ traverse_object (type& c) if (versioned) { os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));" + "sts.version_migration (" << schema_name << "));" << endl; svm = true; } @@ -2444,7 +2459,7 @@ traverse_object (type& c) if (erase_versioned_containers && !svm) os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; + "sts.version_migration (" << schema_name << "));"; os << endl; @@ -2534,15 +2549,15 @@ traverse_object (type& c) os << "}"; - if (versioned) - os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << "statements_type& sts (" << endl << "conn.statement_cache ().find_object ());"; + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + if (poly_derived) os << "root_statements_type& rsts (sts.root_statements ());"; @@ -2727,15 +2742,15 @@ traverse_object (type& c) if (!abst) { - if (versioned) - os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << "statements_type& sts (" << endl << "conn.statement_cache ().find_object ());"; + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + if (poly_derived) os << "root_statements_type& rsts (sts.root_statements ());"; @@ -2833,15 +2848,15 @@ traverse_object (type& c) if (!abst) { - if (versioned) - os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << "statements_type& sts (" << endl << "conn.statement_cache ().find_object ());"; + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + if (poly_derived) os << "root_statements_type& rsts (sts.root_statements ());"; @@ -3407,9 +3422,8 @@ traverse_object (type& c) user_sections::count_all | user_sections::count_versioned_only) != 0)) { - os << "const schema_version_migration& svm (" << endl - << "sts.connection ().database ().schema_version_migration (" << - schema_name << "));" + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));" << endl; } @@ -3529,7 +3543,7 @@ traverse_object (type& c) if (versioned) os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));" + "sts.version_migration (" << schema_name << "));" << endl; // Avoid trying to execute an empty SELECT statement. @@ -3746,25 +3760,24 @@ traverse_object (type& c) // os << "result< " << traits << "::object_type >" << endl << traits << "::" << endl - << "query (database& db, const query_base_type& q)" + << "query (database&, const query_base_type& q)" << "{" - << "ODB_POTENTIALLY_UNUSED (db);" - << endl << "using namespace " << db << ";" << "using odb::details::shared;" << "using odb::details::shared_ptr;" << endl; - if (versioned) - os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << endl << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object ());" - << endl; + << "conn.statement_cache ().find_object ());"; + + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + + os << endl; // Rebind the image if necessary. // @@ -3883,17 +3896,17 @@ traverse_object (type& c) << "using odb::details::shared_ptr;" << endl; - if (versioned) - os << "const schema_version_migration& svm (" << endl - << "c.database ().schema_version_migration (" << - schema_name << "));"; - os << db << "::connection& conn (" << endl << "static_cast<" << db << "::connection&> (c));" << endl << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object ());" - << endl; + << "conn.statement_cache ().find_object ());"; + + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + + os << endl; // Rebind the image if necessary. // @@ -3975,11 +3988,6 @@ traverse_object (type& c) << "static_cast (pq.stmt.get ())));" << endl; - if (versioned) - os << "const schema_version_migration& svm (" << endl - << "st->connection ().database ().schema_version_migration (" << - schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << endl @@ -3989,8 +3997,13 @@ traverse_object (type& c) << "assert (&conn == &st->connection ());" << endl << "statements_type& sts (" << endl - << "conn.statement_cache ().find_object ());" - << endl; + << "conn.statement_cache ().find_object ());"; + + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + + os << endl; // Rebind the image if necessary. // @@ -4960,24 +4973,23 @@ traverse_view (type& c) { os << "result< " << traits << "::view_type >" << endl << traits << "::" << endl - << "query (database& db, const query_base_type& q)" + << "query (database&, const query_base_type& q)" << "{" - << "ODB_POTENTIALLY_UNUSED (db);" - << endl << "using namespace " << db << ";" << "using odb::details::shared;" << "using odb::details::shared_ptr;" << endl; - if (versioned) - os << "const schema_version_migration& svm (" << - "db.schema_version_migration (" << schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << "statements_type& sts (" << endl - << "conn.statement_cache ().find_view ());" - << endl + << "conn.statement_cache ().find_view ());"; + + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + + os << endl << "image_type& im (sts.image ());" << "binding& imb (sts.image_binding ());" << endl @@ -5039,16 +5051,16 @@ traverse_view (type& c) << "using odb::details::shared_ptr;" << endl; - if (versioned) - os << "const schema_version_migration& svm (" << endl - << "c.database ().schema_version_migration (" << - schema_name << "));"; - os << db << "::connection& conn (" << endl << "static_cast<" << db << "::connection&> (c));" << "statements_type& sts (" << endl - << "conn.statement_cache ().find_view ());" - << endl; + << "conn.statement_cache ().find_view ());"; + + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + + os << endl; // Rebind the image if necessary. // @@ -5109,11 +5121,6 @@ traverse_view (type& c) << "static_cast (pq.stmt.get ())));" << endl; - if (versioned) - os << "const schema_version_migration& svm (" << endl - << "st->connection ().database ().schema_version_migration (" << - schema_name << "));"; - os << db << "::connection& conn (" << endl << db << "::transaction::current ().connection ());" << endl @@ -5123,8 +5130,13 @@ traverse_view (type& c) << "assert (&conn == &st->connection ());" << endl << "statements_type& sts (" << endl - << "conn.statement_cache ().find_view ());" - << endl; + << "conn.statement_cache ().find_view ());"; + + if (versioned) + os << "const schema_version_migration& svm (" << + "sts.version_migration (" << schema_name << "));"; + + os << endl; // Rebind the image if necessary. // diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index d4bc7a8..ac81bdf 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -4820,8 +4820,8 @@ namespace relational if (s.versioned || s.versioned_containers) os << "const schema_version_migration& svm (" << endl - << "esc." << m.name () << ".connection ().database ()." << - "schema_version_migration (" << schema_name << "));" + << "esc." << m.name () << ".version_migration (" << + schema_name << "));" << endl; // Load values, if any. @@ -5097,8 +5097,8 @@ namespace relational if (s.versioned || s.readwrite_versioned_containers) os << "const schema_version_migration& svm (" << endl - << "esc." << m.name () << ".connection ().database ()." << - "schema_version_migration (" << schema_name << "));" + << "esc." << m.name () << ".version_migration (" << + schema_name << "));" << endl; // Update values, if any. -- cgit v1.1