Skip to content

Commit

Permalink
Issue 213: make db.reset() explicit (#222)
Browse files Browse the repository at this point in the history
* add prototype

While the method was being used by dawige.db.view() there was no prototype that identified its existence. Added it with basic comments.

* implementation for shelve

While dawgie.db.post already implemented dawgie.db.reset(), needed dawgie.db.shelve to do the same thing.

* test dawgie.db.reset()

Both dawgie.db.post and dawgie.db.shelve behave the same.
  • Loading branch information
al-niessner authored Dec 21, 2023
1 parent f47a0aa commit 9beca4d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
17 changes: 16 additions & 1 deletion Python/dawgie/db/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,21 @@ def reopen()->bool:
'''
return _db_in_use().reopen()

def reset (runid:int, tn:str, tskn:str, alg:dawgie.Algorithm):
'''Reset the algorithm version
The version of the algorithm may be different than the one recorded for
the given runID. The reset() alters the version of the algorithm to match
that recorded with the given runID.
This reset then descends down into state vectors and values doing the same
version reset.
Once the objects have the correct versions, the rest of the database calls
can be used to look up their correct content.
'''
return _db_in_use().reset (runid, tn, tskn, alg)

def retreat (reg, ret)->dawgie.Timeline:
'''Get a dawgie.Timeline from the database backend
Expand Down Expand Up @@ -264,7 +279,7 @@ def view (visitor, runid, tn, tskn, algn, svn):
visitor.add_declaration (msg)
return

_db_in_use().reset (runid, tn, tskn, alg) # set the alg version
reset (runid, tn, tskn, alg) # set the alg version
ds = connect (alg, bot, tn)
ds.load()

Expand Down
25 changes: 23 additions & 2 deletions Python/dawgie/db/shelve/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,29 @@ def reopen()->bool:
'''
return DBI().reopen()

def reset (_runid:int, _tn:str, _tskn, _alg)->None:
log.warning('reset() is not implemented for shelve')
def reset (runid:int, tn:str, tskn, alg)->None:
# Need to set the version value which is a private function
# so, pylint: disable=protected-access
if not DBI().is_open: raise RuntimeError('called next before open')
if DBI().is_reopened: raise RuntimeError('called outside of Foreman context')

pk = [runid, DBI().tables.target[tn], DBI().tables.task[tskn]]
ptab = util.subset (DBI().tables.prime, str(tuple(pk)).replace (')', ','))
for algi in util.subset (DBI().tables.alg, alg.name(), [pk[-1]]).values():
tab = util.subset(DBI().tables.prime,
str(tuple(pk + [algi])).replace (')', ','))
if tab:
ptab = tab
break
pass
for pk in util.prime_keys(ptab):
aid,svid = pk[-3:-1]
alg._set_ver (util.dissect(DBI().indices.alg[aid])[-1]._get_ver())
svn,ver = util.dissect(DBI().indices.state[svid])[1:]
if svn in alg.sv_as_dict():
alg.sv_as_dict()[svn]._set_ver(ver._get_ver())
pass
pass
return

def retreat (reg, ret)->dawgie.Timeline:
Expand Down
21 changes: 16 additions & 5 deletions Python/dawgie/db/shelve/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,23 @@ def rotated_files(index=None):
orig += glob.glob(f"{path}/{index:d}.{dawgie.context.db_name}.value")
return orig

def subset (from_table:{str:int}, name:str, parents:[int])->{}:
'''extract a subset of table as a dictionary'''
def subset (from_table:{str:int}, name:str, parents:[int]=None)->{}:
'''extract a subset of table as a dictionary
It behaves two different ways. If parnets is provided, then it will use
util.construct() to generate the full name given the parents. If parents is
not given, then it will simply use name.
'''
result = {}
for parent in parents:
surname = construct (name, parent)
result.update (dict(filter(lambda t,sn=surname:t[0].startswith (sn),
if parents:
for parent in parents:
surname = construct (name, parent)
result.update (dict(filter(lambda t,sn=surname:t[0].startswith (sn),
from_table.items())))
pass
pass
else:
result.update (dict(filter(lambda t,sn=name:t[0].startswith (sn),
from_table.items())))
pass
return result
34 changes: 34 additions & 0 deletions Test/test_13.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,40 @@ def test_reopen(self):
self.assertFalse(True)
return

def test_reset(self):
tgt,tsk,alg = dawgie.db.testdata.DATASETS[-1]
print (tgt, tsk._name(), alg.name())
alg._set_ver(dawgie.VERSION(100,100,100))
for sv in alg.state_vectors():
sv._set_ver(dawgie.VERSION(200,200,200))
for val in sv.values():
val._set_ver(dawgie.VERSION(400,500,600))
pass
pass
print (type(alg.design()),alg.design())
dawgie.db.close()
self.assertRaises (RuntimeError, dawgie.db.reset,
dawgie.db.testdata.RUNID, tgt, tsk._name(), alg)
dawgie.db.open()
dawgie.db.reset (dawgie.db.testdata.RUNID, tgt, tsk._name(), alg)
dawgie.db.close()
print (type(alg.design()),alg.design())
self.assertEqual (alg.design(), 1, 'design')
self.assertEqual (alg.implementation(), 1, 'implementation')
self.assertEqual (alg.bugfix(), 2, 'bugfix')
for sv in alg.state_vectors():
self.assertEqual (sv.design(), 1, 'design')
self.assertEqual (sv.implementation(), 2, 'implementation')
self.assertEqual (sv.bugfix(), 3, 'bugfix')
# these should not have changed
for val in sv.values():
self.assertEqual (val.design(), 400, 'design')
self.assertEqual (val.implementation(), 500, 'implementation')
self.assertEqual (val.bugfix(), 600, 'bugfix')
pass
pass
return

def test_retreat(self):
ret,reg = dawgie.db.testdata.TIMELINES[0]
dawgie.db.close()
Expand Down

0 comments on commit 9beca4d

Please sign in to comment.