Don't db.commit() so frequently.

Just commit when we're about to do something blocking.  sqlite goes a lot
faster with bigger transactions.  This change does show a small percentage
speedup in tests, but not as much as I'd like.
This commit is contained in:
Avery Pennarun 2010-12-09 02:44:33 -08:00
commit 29d6c9a746
2 changed files with 35 additions and 22 deletions

View file

@ -104,6 +104,7 @@ class BuildJob:
dof = state.File(name=dofile) dof = state.File(name=dofile)
dof.set_static() dof.set_static()
dof.save() dof.save()
state.commit()
jwack.start_job(t, self._do_subproc, self._after) jwack.start_job(t, self._do_subproc, self._after)
def _do_subproc(self): def _do_subproc(self):
@ -184,6 +185,7 @@ class BuildJob:
try: try:
self.donefunc(self.t, rv) self.donefunc(self.t, rv)
assert(self.lock.owned) assert(self.lock.owned)
state.commit()
finally: finally:
self.lock.unlock() self.lock.unlock()
@ -205,6 +207,7 @@ def main(targets, shouldbuildfunc):
# In the first cycle, we just build as much as we can without worrying # In the first cycle, we just build as much as we can without worrying
# about any lock contention. If someone else has it locked, we move on. # about any lock contention. If someone else has it locked, we move on.
for t in targets: for t in targets:
state.commit()
jwack.get_token(t) jwack.get_token(t)
if retcode[0] and not vars.KEEP_GOING: if retcode[0] and not vars.KEEP_GOING:
break break
@ -246,4 +249,5 @@ def main(targets, shouldbuildfunc):
lock.unlock() lock.unlock()
else: else:
BuildJob(t, lock, shouldbuildfunc, done).start() BuildJob(t, lock, shouldbuildfunc, done).start()
state.commit()
return retcode[0] return retcode[0]

View file

@ -1,6 +1,7 @@
import sys, os, errno, glob, stat, sqlite3 import sys, os, errno, glob, stat, sqlite3
import vars import vars
from helpers import unlink, err, debug2, debug3, mkdirp, close_on_exec from helpers import unlink, err, debug2, debug3, mkdirp, close_on_exec
import helpers
SCHEMA_VER=1 SCHEMA_VER=1
TIMEOUT=60 TIMEOUT=60
@ -47,16 +48,15 @@ def db():
" primary key (target,source))") " primary key (target,source))")
_db.execute("insert into Schema (version) values (?)", [SCHEMA_VER]) _db.execute("insert into Schema (version) values (?)", [SCHEMA_VER])
_db.execute("insert into Runid default values") # eat the '0' runid _db.execute("insert into Runid default values") # eat the '0' runid
_db.commit()
if not vars.RUNID: if not vars.RUNID:
_db.execute("insert into Runid default values") _db.execute("insert into Runid default values")
_db.commit()
vars.RUNID = _db.execute("select last_insert_rowid()").fetchone()[0] vars.RUNID = _db.execute("select last_insert_rowid()").fetchone()[0]
os.environ['REDO_RUNID'] = str(vars.RUNID) os.environ['REDO_RUNID'] = str(vars.RUNID)
_db.execute("pragma journal_mode = PERSIST") _db.execute("pragma journal_mode = PERSIST")
_db.execute("pragma synchronous = off") _db.execute("pragma synchronous = off")
_db.commit()
return _db return _db
@ -70,6 +70,22 @@ def init():
os.unlink(f) os.unlink(f)
_wrote = 0
def _write(q, l):
global _wrote
_wrote += 1
#helpers.log_('W: %r %r\n' % (q,l))
db().execute(q, l)
def commit():
global _wrote
if _wrote:
#helpers.log_("COMMIT (%d)\n" % _wrote)
db().commit()
_wrote = 0
_insane = None _insane = None
def is_sane(): def is_sane():
global _insane global _insane
@ -139,8 +155,7 @@ class File(object):
if not name: if not name:
raise Exception('File with id=%r not found and ' raise Exception('File with id=%r not found and '
'name not given' % id) 'name not given' % id)
d.execute('insert into Files (name) values (?)', [name]) _write('insert into Files (name) values (?)', [name])
d.commit()
row = d.execute(q, l).fetchone() row = d.execute(q, l).fetchone()
assert(row) assert(row)
self._init_from_cols(row) self._init_from_cols(row)
@ -149,15 +164,14 @@ class File(object):
if not os.path.exists('%s/.redo' % vars.BASE): if not os.path.exists('%s/.redo' % vars.BASE):
# this might happen if 'make clean' removes the .redo dir # this might happen if 'make clean' removes the .redo dir
return return
d = db() _write('update Files set '
d.execute('update Files set '
' is_generated=?, checked_runid=?, changed_runid=?, ' ' is_generated=?, checked_runid=?, changed_runid=?, '
' stamp=?, csum=? ' ' stamp=?, csum=? '
' where rowid=?', ' where rowid=?',
[self.is_generated, self.checked_runid, self.changed_runid, [self.is_generated,
self.checked_runid, self.changed_runid,
self.stamp, self.csum, self.stamp, self.csum,
self.id]) self.id])
d.commit()
def set_checked(self): def set_checked(self):
self.checked_runid = vars.RUNID self.checked_runid = vars.RUNID
@ -199,21 +213,16 @@ class File(object):
def zap_deps(self): def zap_deps(self):
debug2('zap-deps: %r\n' % self.name) debug2('zap-deps: %r\n' % self.name)
db().execute('delete from Deps where target=?', [self.id]) _write('delete from Deps where target=?', [self.id])
db().commit()
def add_dep(self, mode, dep): def add_dep(self, mode, dep):
src = File(name=dep) src = File(name=dep)
reldep = relpath(dep, vars.BASE) reldep = relpath(dep, vars.BASE)
debug2('add-dep: %r < %s %r\n' % (self.name, mode, reldep)) debug2('add-dep: %r < %s %r\n' % (self.name, mode, reldep))
assert(src.name == reldep) assert(src.name == reldep)
d = db() _write("insert or replace into Deps "
d.execute("delete from Deps where target=? and source=?",
[self.id, src.id])
d.execute("insert into Deps "
" (target, mode, source) values (?,?,?)", " (target, mode, source) values (?,?,?)",
[self.id, mode, src.id]) [self.id, mode, src.id])
d.commit()
def read_stamp(self): def read_stamp(self):
try: try: