Commit e5203906 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 45fde82f
...@@ -1616,7 +1616,8 @@ func main() { ...@@ -1616,7 +1616,8 @@ func main() {
// If a user opens it, it will start to get tids of through which // If a user opens it, it will start to get tids of through which
// zhead.at was, starting from the time when .wcfs/zhead was opened. // zhead.at was, starting from the time when .wcfs/zhead was opened.
// There can be multiple openers. Once opened, the file must be read, // There can be multiple openers. Once opened, the file must be read,
// as wcfs blocks waiting for data to be read before XXX. // as wcfs blocks waiting for data to be read when processing
// invalidations.
mkfile(&_wcfs, "zhead", &_wcfs_Zhead{ mkfile(&_wcfs, "zhead", &_wcfs_Zhead{
fsNode: newFSNode(fSticky), fsNode: newFSNode(fSticky),
}) })
......
...@@ -147,7 +147,7 @@ class tDB: ...@@ -147,7 +147,7 @@ class tDB:
t._headv.append(head) t._headv.append(head)
return head return head
# wcsync makes sure wc synchronized to latest committed transaction. # wcsync makes sure wcfs synchronized to latest committed transaction.
def wcsync(t): def wcsync(t):
while len(t._wc_zheadv) < len(t._headv): while len(t._wc_zheadv) < len(t._headv):
l = t._wc_zheadfh.readline() l = t._wc_zheadfh.readline()
...@@ -177,16 +177,54 @@ class tDB: ...@@ -177,16 +177,54 @@ class tDB:
return os.path.join(t.wc.mountpoint, obj) return os.path.join(t.wc.mountpoint, obj)
# read reads file corresponding to obj on wcfs # read reads file corresponding to obj on wcfs.
def read(t, obj, at=None): def read(t, obj, at=None):
path = t.path(obj, at=at) path = t.path(obj, at=at)
return readfile(path) return readfile(path)
# stat stats file corresponding to obj on wcfs # stat stats file corresponding to obj on wcfs.
def stat(t, obj, at=None): def stat(t, obj, at=None):
path = t.path(obj, at=at) path = t.path(obj, at=at)
return os.stat(path) return os.stat(path)
# open opens file corresponding to obj on wcfs.
def open(t, obj, at=None):
path = t.path(obj, at=at)
return open(path)
# readblk reads ZBigFile[blk] from wcfs.
@func
def readblk(t, zf, blk, at=None):
assert isinstance(zf, ZBigFile)
f = t.open(zf, at=at) # XXX binary, !buffered
defer(f.close)
blksize = zf.blksize
f.seek(blk*blksize)
n = blksize
data = b''
while n > 0:
chunk = f.read(n)
assert len(chunk) > 0
data += chunk
n -= len(chunk)
return data
# assertData asserts that wcfs file corresponding to zf has data blocks as specified in expectv.
#
# Expected blocks may be given with size < zf.blksize. In such case they
# are implicitly appended with trailing zeros.
def assertData(t, zf, expectv, at=None):
assert isinstance(zf, ZBigFile)
data = t.read(zf, at=at)
assert len(data) == len(expectv)*zf.blksize
for i, blk in enumerate(expectv):
assert len(blk) <= zf.blksize
blk += b'\0'*(zf.blksize - len(blk)) # trailing zeros
assert data[i*zf.blksize:(i+1)*zf.blksize] == blk
# XXX text ... # XXX text ...
# XXX parametrize zblk0, zblk1 XXX or just rely on tox? # XXX parametrize zblk0, zblk1 XXX or just rely on tox?
...@@ -213,11 +251,9 @@ def test_wcfs(): ...@@ -213,11 +251,9 @@ def test_wcfs():
assert _.st_size == 0 assert _.st_size == 0
assert _.st_mtime == tidtime(tid1) assert _.st_mtime == tidtime(tid1)
# commit data to f and make sure we can see it on wcfs # commit data to f and make sure we can see it on wcfs
# use !wcfs mode so that we prepare data independently of wcfs code paths. # use !wcfs mode so that we prepare data independently of wcfs code paths.
#hole = 10 XXX reenable hole = 10
hole = 1
fh = f.fileh_open(_use_wcfs=False) fh = f.fileh_open(_use_wcfs=False)
vma = fh.mmap(hole, 1) # 1 page at offset=10 vma = fh.mmap(hole, 1) # 1 page at offset=10
s = b"hello world" s = b"hello world"
...@@ -226,13 +262,18 @@ def test_wcfs(): ...@@ -226,13 +262,18 @@ def test_wcfs():
t.commit() t.commit()
t.wcsync() # sync wcfs to ZODB t.wcsync() # sync wcfs to ZODB
# we wrote "hello world" after hole'th block, but size is always mutiple of blksize. fsize = (hole + 1)*blksize # size is always mutiple of blksize.
fsize = (hole + 1)*blksize
_ = t.stat(f) _ = t.stat(f)
assert _.st_size == fsize assert _.st_size == fsize
assert _.st_mtime == tidtime(t.head) assert _.st_mtime == tidtime(t.head)
t.assertData(f, [b'']*hole + [s])
for i in range(hole):
assert t.readblk(f, i) == b'\0'*blksize
assert t.readblk(f, hole) == s + b'\0'*(blksize - len(s))
data = t.read(f) data = t.read(f)
assert len(data) == fsize assert len(data) == fsize
for i in range(hole): for i in range(hole):
......
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