FSAccessor: Make the fileSize and narOffset fields optional

The narOffset field only applies to NAR accessors. The fileSize field
may be too expensive to compute for certain accessors (e.g. libgit).
This commit is contained in:
Eelco Dolstra 2023-11-01 15:39:40 +01:00
parent 5381123879
commit 50aae0a14c
3 changed files with 9 additions and 8 deletions

View file

@ -23,7 +23,7 @@ public:
/**
* For regular files only: the size of the file.
*/
uint64_t fileSize = 0;
std::optional<uint64_t> fileSize;
/**
* For regular files only: whether this is an executable.
*/
@ -32,7 +32,7 @@ public:
* For regular files only: the position of the contents of this
* file in the NAR.
*/
uint64_t narOffset = 0;
std::optional<uint64_t> narOffset;
};
virtual ~FSAccessor() { }

View file

@ -210,10 +210,10 @@ struct NarAccessor : public FSAccessor
if (i.stat.type != Type::tRegular)
throw Error("path '%1%' inside NAR file is not a regular file", path);
if (getNarBytes) return getNarBytes(i.stat.narOffset, i.stat.fileSize);
if (getNarBytes) return getNarBytes(*i.stat.narOffset, *i.stat.fileSize);
assert(nar);
return std::string(*nar, i.stat.narOffset, i.stat.fileSize);
return std::string(*nar, *i.stat.narOffset, *i.stat.fileSize);
}
std::string readLink(const Path & path) override
@ -253,11 +253,12 @@ json listNar(ref<FSAccessor> accessor, const Path & path, bool recurse)
switch (st->type) {
case SourceAccessor::Type::tRegular:
obj["type"] = "regular";
obj["size"] = st->fileSize;
if (st->fileSize)
obj["size"] = *st->fileSize;
if (st->isExecutable)
obj["executable"] = true;
if (st->narOffset)
obj["narOffset"] = st->narOffset;
if (st->narOffset && *st->narOffset)
obj["narOffset"] = *st->narOffset;
break;
case SourceAccessor::Type::tDirectory:
obj["type"] = "directory";

View file

@ -52,7 +52,7 @@ struct MixLs : virtual Args, MixJSON
(st->isExecutable ? "-r-xr-xr-x" : "-r--r--r--") :
st->type == FSAccessor::Type::tSymlink ? "lrwxrwxrwx" :
"dr-xr-xr-x";
auto line = fmt("%s %20d %s", tp, st->fileSize, relPath);
auto line = fmt("%s %20d %s", tp, st->fileSize.value_or(0), relPath);
if (st->type == FSAccessor::Type::tSymlink)
line += " -> " + accessor->readLink(curPath);
logger->cout(line);