Commit 14288168 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent a0a3d2ad
......@@ -593,6 +593,34 @@ class tSrvReq:
# ---- watch setup/adjust ----
# _pinAt returns which blocks needs to be pinned for zf@at.
#
# it does not take into account whether blocks are in cache or not and computes
# pin from all changes.
@func(tWatch)
def _pinAt(w, zf, at): # -> pin = {} blk -> rev
t = w.tdb
# all changes to zf
vdf = [_.byfile[zf] for _ in t.dFtail if zf in _.byfile]
# {} blk -> at for changes ∈ (at, head]
pin = {}
for df in [_ for _ in vdf if _.rev > at]:
for blk in df.ddata:
if blk in pin:
continue
# history of blk changes <= at
blkhistoryat = [_.rev for _ in vdf if blk in _.ddata and _.rev <= at]
if len(blkhistoryat) == 0:
pinrev = t._headv[0] # was hole - at0 XXX -> pin to @00?
else:
pinrev = max(blkhistoryat)
assert pinrev <= at
pin[blk] = pinrev
return pin
# watch sets up a watch for file@at.
# XXX and verifies that wcfs sends correct initial pins?
# XXX or adjusts
......@@ -605,28 +633,34 @@ def watch(w, zf, at): # XXX -> ?
at_from = '(%s ->) ' % t.hat(at_prev)
print('\nC: setup watch f<%s> %s%s' % (h(zf._p_oid), at_from, t.hat(at)))
pin_prev = {}
if at_prev is not None:
assert False # TODO
assert at_prev <= at, 'TODO %s -> %s' % (t.hat(at_prev), t.hat(at))
pin_prev = w._pinAt(zf, at_prev)
pin = w._pinAt(zf, at)
for blk in set(pin_prev.keys()).union(pin.keys()):
# blk ∉ pin_prev, blk ∉ pin -> cannot happen
assert (blk in pin_prev) or (blk in pin)
# blk ∉ pin_prev, blk ∈ pin -> cannot happen
if at_prev is not None:
if blk not in pin_prev and blk in pin:
assert False, '#%d pinned %s; not pinned %s' % (t.hat(at_prev), t.hat(at))
# blk ∈ pin_prev, blk ∉ pin -> unpin to head
if blk in pin_prev and blk not in pin:
pin[blk] = None # XXX = head
# blk ∈ pin_prev, blk ∈ pin -> use pin
if blk in pin_prev and blk in pin:
assert pin[blk] >= pin_prev[blk]
# all changes to zf
vdf = [_.byfile[zf] for _ in t.dFtail if zf in _.byfile]
# {} blk -> at that have to be pinned
# XXX also check that head/file[blk] is in cache - else no need to pin
pinok = {}
for df in [_ for _ in vdf if _.rev > at]:
for blk in df.ddata:
if blk in pinok:
continue
# history of blk changes <= at
# XXX -> > at_prev?
blkhistoryat = [_.rev for _ in vdf if blk in _.ddata and _.rev <= at]
if len(blkhistoryat) == 0:
pinrev = t._headv[0] # was hole - at0 XXX -> pin to @00?
else:
pinrev = max(blkhistoryat)
pinok[blk] = pinrev
pinok = pin
pinokv = ['%d: %s' % (blk, t.hat(pinok[blk])) for blk in sorted(pinok.keys())]
print('# pinok: {%s}' % ', '.join(pinokv))
......@@ -764,11 +798,20 @@ def test_wcfs():
w.watch(zf, dF.rev)
w.close()
# watch going at_i -> at_j
print('\n--------')
for dF_from in t.dFtail:
for dF_to in t.dFtail:
if not (dF_from.rev <= dF_to.rev):
continue # FIXME TODO test all directions
w = t.openwatch()
w.watch(zf, dF_from.rev)
w.watch(zf, dF_to.rev)
w.close()
# watch going at1 -> at2 -> at3
w = t.openwatch()
for dF in t.dFtail:
w.watch(zf, dF.rev)
print('\n--------')
print()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment