Commit 821d3909 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent cd8d9105
......@@ -94,16 +94,19 @@ class Conn(object):
# _File represent isolated file view under Conn.
class _File(object):
# .wconn Conn
# .foid hex of ZBigFile root object ID
# .headf file object of head/file
# .pin {} blk -> rev that wcfs already sent us for this file
# .pinned {} blk -> rev that wcfs already sent us for this file
# .mmaps []_Mapping ↑blk_start mappings of this file
pass
# _Mapping represents one mapping of _File.
class _Mapping(object):
# .mem mmaped memory
# .file _File
# .blk_start offset of this mapping in file
# .mem mmaped memory
pass
# XXX property .blk_stop = blk_start + len(mem) // blksize & assert len(mem) % blksize == 0
......@@ -130,31 +133,52 @@ def _pinner(wconn, ctx):
if not (mmap.blk_start <= req.blk && req.blk < mmap.blk_stop):
continue
# this mmap covers f[blk] - let's remmap it to @rev/f or head/f
if req.at is None:
fsfile = f.headf
else:
# TODO share @rev fd until Conn is recynced?
fsfile = wconn._wc._open("@%s/%s" % (ashex(req.at), ashex(req.foid))):
# FIXME check if virtmem did not mapped RW page into this block already
mm.mmap_into_ro(mmap.mem[(req.blk-mmap.blk_start)*blksize:][:blksize], fsfile.fileno(), req.blk*blksize)
if req.at is not None:
fsfile.close()
mmap.pin(req.blk, req.at)
# update .pin
# update .pinned
if req.at is None:
f.pin.pop(req.blk, None) # = delete(f.pin, req.blk) -- unpin to @head
f.pinned.pop(req.blk, None) # = delete(f.pinned, req.blk) -- unpin to @head
else:
f.pin[req.blk] = req.at
f.pinned[req.blk] = req.at
# pin remmaps mapping memory for [blk] to be viewing database as of @at state.
#
# at=None means unpin to head/ .
# NOTE this does not check wrt virtmem already mapped blk as RW XXX ok?
@func(_Mapping)
def pin(mmap, blk, at):
f = mmap.file
if at is None:
fsfile = f.headf
else:
# TODO share @rev fd until wconn is recynced?
fsfile = f.wconn._wc._open("@%s/%s" % (ashex(at), ashex(f.foid)), "rb")
defer(fsfile.close)
mm.mmap_into_ro(mmap.mem[(blk-mmap.blk_start)*blksize:][:blksize], fsfile.fileno(), blk*blksize)
# mmap creats file mapping representing file data as of wconn.at database state.
@func(Conn)
def mmap(wconn, foid, offset, size): # -> Mapping XXX offset, size -> blkoff, blksize ?
# XXX
with wconn._filemu:
f = wconn._filetab.get(foid)
if f is None:
headf = wconn._wc._open("head/%s" % (ashex(foid),), "rb")
f = File(headf)
wconn._filetab[foid] = f
# XXX relock wconn -> f ?
# create memory with head/f mapping and applied pins
mem = mm.mmap_ro(f.headf.fileno(), offset, size)
for blk, rev in f.pin.items(): # XXX keep f.pin ↑blk and use binary search?
if not (blk_start <= blk && blk < blk_stop):
continue # blk out of this mapping
mm.mmap_into_ro(mem[(blk - blk_start)*blksize:][:blksize],
# XXX Watch
......
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