Distinguish chunk or list files with directory entry type

This commit is contained in:
Ehmry - 2018-09-12 19:25:02 +02:00
parent 3006147fa7
commit be35d47ad3
1 changed files with 27 additions and 22 deletions

View File

@ -8,14 +8,15 @@ type EntryKey = enum
sizeKey = 3
type FsType* = enum
ufsFile = 0,
ufsDir = 1
fsFileList = 0,
fsDirChunk = 1,
fsFileChunk = 2,
type FsKind* = enum
fileNode,
dirNode,
shallowDir,
shallowFile
shallowDirChunk,
shallowFileList,
type
FileLink* = object
@ -29,19 +30,19 @@ type
links*: seq[FileLink]
of dirNode:
entries: OrderedTable[string, FsNode]
of shallowFile, shallowDir:
of shallowFileList, shallowDirChunk:
discard
size: BiggestInt
proc isRaw*(file: FsNode): bool =
file.links.len == 0
(file.kind == fileNode) and (file.links.len == 0)
proc cid*(u: FsNode): Cid =
assert u.cid.isValid
u.cid
proc isFile*(u: FsNode): bool = u.kind in { fileNode, shallowFile }
proc isDir*(u: FsNode): bool = u.kind in { dirNode, shallowDir }
proc isFile*(u: FsNode): bool = u.kind in { fileNode, shallowFileList }
proc isDir*(u: FsNode): bool = u.kind in { dirNode, shallowDirChunk }
proc size*(u: FsNode): BiggestInt =
if u.kind == dirNode: u.entries.len.BiggestInt
@ -108,16 +109,19 @@ proc toCbor*(u: FsNode): CborNode =
for name, node in u.entries:
var entry = newCborMap()
case node.kind
of fileNode, shallowFile:
entry[typeKey.int] = ufsFile.int.newCborInt
of fileNode, shallowFileList:
if node.isRaw:
entry[typeKey.int] = fsFileChunk.int.newCborInt
else:
entry[typeKey.int] = fsFileList.int.newCborInt
entry[dataKey.int] = node.cid.newCborBytes
entry[sizeKey.int] = node.size.newCborInt
of dirNode:
entry[typeKey.int] = ufsDir.int.newCborInt
entry[typeKey.int] = fsDirChunk.int.newCborInt
entry[dataKey.int] = node.cid.newCborBytes
entry[sizeKey.int] = node.entries.len.newCborInt
of shallowdir:
entry[typeKey.int] = ufsDir.int.newCborInt
of shallowDirChunk:
entry[typeKey.int] = fsDirChunk.int.newCborInt
entry[dataKey.int] = node.cid.newCborBytes
entry[sizeKey.int] = node.size.int.newCborInt
map[name] = entry
@ -193,8 +197,11 @@ proc parseFs*(raw: string; cid: Cid): FsNode =
of typeKey:
next c
case c.readInt.FsType
of ufsFile: entry.kind = shallowFile
of ufsDir: entry.kind = shallowDir
of fsFileList: entry.kind = shallowFileList
of fsDirChunk: entry.kind = shallowDirChunk
of fsFileChunk:
entry.kind = fileNode
entry.links = newSeq[FileLink](0)
of dataKey:
next c
c.readBytes buf
@ -272,6 +279,7 @@ proc addFile*(store: DagfsStore; path: string): FsNode =
if u.links.len == 1:
# take a shortcut use the raw chunk CID
u.cid = u.links[0].cid
u.links.setLen 0
else:
u.cid = store.putDag(u.toCbor)
result = u
@ -281,9 +289,9 @@ proc addDir*(store: DagfsStore; dirPath: string): FsNode =
for kind, path in walkDir dirPath:
var child: FsNode
case kind
of pcFile:
of pcFile, pcLinkToFile:
child = store.addFile path
of pcDir:
of pcDir, pcLinkToDir:
child = store.addDir(path)
else: continue
dRoot.add path.extractFilename, child
@ -320,7 +328,7 @@ proc walk*(store: DagfsStore; dir: FsNode; path: string; cache = true): FsNode =
if next.isNil:
result = nil
break
if (next.kind in {shallowFile, shallowDir}):
if (next.kind in {shallowFileList, shallowDirChunk}):
store.get(next.cid, raw)
next = parseFs(raw, next.cid)
if cache:
@ -350,16 +358,13 @@ proc readBuffer*(store: DagfsStore; file: FsNode; pos: BiggestInt;
filePos = 0
chunk = ""
if pos < file.size:
#[
if file.cid.isRaw:
if file.isRaw:
let pos = pos.int
store.get(file.cid, chunk)
if pos < chunk.high:
copyMem(buf, chunk[pos].addr, min(chunk.len - pos, size))
result = size
else:
]#
block:
for i in 0..file.links.high:
let linkSize = file.links[i].size
if filePos <= pos and pos < filePos+linkSize: