From e3efc0e465bb7d6d609d4efc26964c4c40de98ef Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Thu, 4 Oct 2018 02:43:15 -0700 Subject: [PATCH] [sql] batch write of attributes Summary: Instead of many successive implicit transactions to write each attributes of the procedures in a file, write them all in a single transaction. Reviewed By: jberdine Differential Revision: D10173351 fbshipit-source-id: 5f2a5ffb5 --- infer/src/IR/SourceFiles.ml | 3 ++- infer/src/base/SqliteUtils.ml | 6 ++++++ infer/src/base/SqliteUtils.mli | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/infer/src/IR/SourceFiles.ml b/infer/src/IR/SourceFiles.ml index 84d8f3933..5958ea5b9 100644 --- a/infer/src/IR/SourceFiles.ml +++ b/infer/src/IR/SourceFiles.ml @@ -52,7 +52,8 @@ let add source_file cfg tenv = (* NOTE: it's important to write attribute files to disk before writing cfgs to disk. OndemandCapture module relies on it - it uses existance of the cfg as a barrier to make sure that all attributes were written to disk (but not necessarily flushed) *) - Cfg.save_attributes source_file cfg ; + SqliteUtils.with_transaction (ResultsDatabase.get_database ()) ~f:(fun () -> + Cfg.save_attributes source_file cfg ) ; ResultsDatabase.with_registered_statement store_statement ~f:(fun db store_stmt -> SourceFile.SQLite.serialize source_file |> Sqlite3.bind store_stmt 1 diff --git a/infer/src/base/SqliteUtils.ml b/infer/src/base/SqliteUtils.ml index 2d0aa090f..81926b1a6 100644 --- a/infer/src/base/SqliteUtils.ml +++ b/infer/src/base/SqliteUtils.ml @@ -95,6 +95,12 @@ let db_close db = (Sqlite3.errmsg db))) +let with_transaction db ~f = + exec db ~log:"begin transaction" ~stmt:"BEGIN IMMEDIATE TRANSACTION" ; + f () ; + exec db ~log:"commit transaction" ~stmt:"COMMIT" + + module type Data = sig type t diff --git a/infer/src/base/SqliteUtils.mli b/infer/src/base/SqliteUtils.mli index 640c4bf46..251c4bf66 100644 --- a/infer/src/base/SqliteUtils.mli +++ b/infer/src/base/SqliteUtils.mli @@ -60,6 +60,9 @@ val result_unit : ?finalize:bool -> Sqlite3.db -> log:string -> Sqlite3.stmt -> val db_close : Sqlite3.db -> unit (** Close the given database and asserts that it was effective. Raises {!Error} if not. *) +val with_transaction : Sqlite3.db -> f:(unit -> unit) -> unit +(** Execute [f] within an explicit sqlite transaction. *) + (** An API commonly needed to store and retrieve objects from the database *) module type Data = sig type t