Commit e563a4e3 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1146656d
...@@ -270,12 +270,6 @@ class tDB: ...@@ -270,12 +270,6 @@ class tDB:
t._wcsync() t._wcsync()
return head return head
# _blkaccess marks head/zf[blk] accessed.
def _blkaccess(t, zf, blk):
# XXX locking
zfAccessed = t._accessed.setdefault(zf, {})
zfAccessed[blk] = t.head
# _wcsync makes sure wcfs is synchronized to latest committed transaction. # _wcsync makes sure wcfs is synchronized to latest committed transaction.
def _wcsync(t): def _wcsync(t):
while len(t._wc_zheadv) < len(t.dFtail): while len(t._wc_zheadv) < len(t.dFtail):
...@@ -291,6 +285,13 @@ class tDB: ...@@ -291,6 +285,13 @@ class tDB:
# head/at = last txn of whole db # head/at = last txn of whole db
assert t.read("head/at") == h(t.head) assert t.read("head/at") == h(t.head)
# _blkaccess marks head/zf[blk] accessed.
# XXX place=?
def _blkaccess(t, zf, blk):
# XXX locking?
zfAccessed = t._accessed.setdefault(zf, {})
zfAccessed[blk] = t.head
# path returns path for object on wcfs. # path returns path for object on wcfs.
# - str: wcfs root + obj; # - str: wcfs root + obj;
...@@ -323,8 +324,7 @@ class tDB: ...@@ -323,8 +324,7 @@ class tDB:
# iter_revv iterates through all possible at_i -> at_j -> at_k ... sequences. # iter_revv iterates through all possible at_i -> at_j -> at_k ... sequences.
# at_i < at_j # at_i < at_j NOTE all sequences go till head.
# NOTE all sequences go till head.
def iter_revv(t, start=z64, level=0): def iter_revv(t, start=z64, level=0):
dFtail = [_ for _ in t.dFtail if _.rev > start] dFtail = [_ for _ in t.dFtail if _.rev > start]
#print(' '*level, 'iter_revv', t.hat(start), [t.hat(_.rev) for _ in dFtail]) #print(' '*level, 'iter_revv', t.hat(start), [t.hat(_.rev) for _ in dFtail])
...@@ -340,7 +340,7 @@ class tDB: ...@@ -340,7 +340,7 @@ class tDB:
# _blkData returns expected zf[blk] data and revision as of @at database state. # _blkData returns expected zf[blk] data and revision as of @at database state.
# #
# If the block is hole (b'', at0) is returned. XXX -> @z64? # If the block is hole - (b'', at0) is returned. XXX -> @z64?
# XXX ret for when the file did not existed at all? blk was after file size? # XXX ret for when the file did not existed at all? blk was after file size?
def _blkData(t, zf, blk, at): # -> (data, rev) def _blkData(t, zf, blk, at): # -> (data, rev)
if at is None: if at is None:
...@@ -412,9 +412,10 @@ class tFile: ...@@ -412,9 +412,10 @@ class tFile:
# stay in pagecache. # stay in pagecache.
# #
# 2. madvise memory with MADV_SEQUENTIAL and MADV_RANDOM in interleaved # 2. madvise memory with MADV_SEQUENTIAL and MADV_RANDOM in interleaved
# mode. This adjusts kernel readahead (which triggers for MADV_SEQUENTIAL # mode. This adjusts kernel readahead (which triggers for
# vma) to not go over to next block and thus a read access to one # MADV_NORMAL or MADV_SEQUENTIAL vma) to not go over to next block
# block won't trigger implicit read access to its neighbour block. # and thus a read access to one block won't trigger implicit read
# access to its neighbour block.
# #
# https://www.quora.com/What-heuristics-does-the-adaptive-readahead-implementation-in-the-Linux-kernel-use # https://www.quora.com/What-heuristics-does-the-adaptive-readahead-implementation-in-the-Linux-kernel-use
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/madvise.c?h=v5.2-rc4#n51 # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/madvise.c?h=v5.2-rc4#n51
...@@ -427,7 +428,7 @@ class tFile: ...@@ -427,7 +428,7 @@ class tFile:
# helps to test how wcfs handles simultaneous read triggered by # helps to test how wcfs handles simultaneous read triggered by
# async kernel readahead vs wcfs uploading data for the same block # async kernel readahead vs wcfs uploading data for the same block
# into OS cache. Also, fully enabled readahead is how wcfs is # into OS cache. Also, fully enabled readahead is how wcfs is
# actually used. # actually used in practice.
assert t.blksize % mm.PAGE_SIZE == 0 assert t.blksize % mm.PAGE_SIZE == 0
t.fmmap = mm.map_ro(t.f.fileno(), 0, t._max_tracked_pages*t.blksize) t.fmmap = mm.map_ro(t.f.fileno(), 0, t._max_tracked_pages*t.blksize)
...@@ -462,6 +463,7 @@ class tFile: ...@@ -462,6 +463,7 @@ class tFile:
t.f.close() t.f.close()
# _blk returns memoryview of file[blk]. # _blk returns memoryview of file[blk].
# when/if block memory is accessed, the user has to notify tDB with _blkaccess call.
def _blk(t, blk): def _blk(t, blk):
assert blk <= t._max_tracked_pages assert blk <= t._max_tracked_pages
return memoryview(t.fmmap[blk*t.blksize:(blk+1)*t.blksize]) return memoryview(t.fmmap[blk*t.blksize:(blk+1)*t.blksize])
...@@ -491,7 +493,7 @@ class tFile: ...@@ -491,7 +493,7 @@ class tFile:
assert st.st_size // t.blksize <= t._max_tracked_pages assert st.st_size // t.blksize <= t._max_tracked_pages
return st.st_size // t.blksize return st.st_size // t.blksize
# assertCache asserts state of OS cache for file. # assertCache asserts on state of OS cache for file.
# #
# incorev is [] of 1/0 representing whether block data is present or not. # incorev is [] of 1/0 representing whether block data is present or not.
def assertCache(t, incorev): def assertCache(t, incorev):
...@@ -537,14 +539,14 @@ class tFile: ...@@ -537,14 +539,14 @@ class tFile:
defer(_) defer(_)
cached = t.cached()[blk] cached = t.cached()[blk]
assert cached in (0, 1) # every check access a block in full assert cached in (0, 1) # every check accesses a block in full
shouldPin = False # whether at least one wlink should receive a pin shouldPin = False # whether at least one wlink should receive a pin
# watches that must be notified if access goes to @head/file # watches that must be notified if access goes to @head/file
wpin = {} # tWatchLink -> pinok wpin = {} # tWatchLink -> pinok
for wlink in t.tdb._wlinks: if t.at is None: # @head/...
pinok = {} for wlink in t.tdb._wlinks:
if t.at is None: # @head/... pinok = {}
w = wlink._watching.get(t.zf) w = wlink._watching.get(t.zf)
if w is not None and w.at < blkrev: if w is not None and w.at < blkrev:
if cached == 1: if cached == 1:
...@@ -558,7 +560,7 @@ class tFile: ...@@ -558,7 +560,7 @@ class tFile:
if blk not in w.pinned: if blk not in w.pinned:
pinok = {blk: t.tdb._blkRev(t.zf, blk, w.at)} pinok = {blk: t.tdb._blkRev(t.zf, blk, w.at)}
shouldPin = True shouldPin = True
wpin[wlink] = pinok wpin[wlink] = pinok
if pinokByWLink is not None: if pinokByWLink is not None:
assert wpin == pinokByWLink, "computed vs explicit pinokByWLink" assert wpin == pinokByWLink, "computed vs explicit pinokByWLink"
......
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