Eliminate some large string copying

This commit is contained in:
Eelco Dolstra 2016-03-04 16:49:56 +01:00
parent ce113c32d2
commit 42bc395b63
5 changed files with 25 additions and 23 deletions

View file

@ -28,7 +28,7 @@ BinaryCacheStore::BinaryCacheStore(std::shared_ptr<Store> localStore,
StringSink sink; StringSink sink;
sink << narVersionMagic1; sink << narVersionMagic1;
narMagic = sink.s; narMagic = *sink.s;
} }
void BinaryCacheStore::init() void BinaryCacheStore::init()
@ -200,14 +200,16 @@ Paths BinaryCacheStore::importPaths(bool requireSignature, Source & source,
struct TeeSource : Source struct TeeSource : Source
{ {
Source & readSource; Source & readSource;
std::string data; ref<std::string> data;
TeeSource(Source & readSource) : readSource(readSource) TeeSource(Source & readSource)
: readSource(readSource)
, data(make_ref<std::string>())
{ {
} }
size_t read(unsigned char * data, size_t len) size_t read(unsigned char * data, size_t len)
{ {
size_t n = readSource.read(data, len); size_t n = readSource.read(data, len);
this->data.append((char *) data, n); this->data->append((char *) data, n);
return n; return n;
} }
}; };
@ -257,7 +259,7 @@ Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath,
Hash h; Hash h;
if (recursive) { if (recursive) {
dumpPath(srcPath, sink, filter); dumpPath(srcPath, sink, filter);
h = hashString(hashAlgo, sink.s); h = hashString(hashAlgo, *sink.s);
} else { } else {
auto s = readFile(srcPath); auto s = readFile(srcPath);
dumpString(s, sink); dumpString(s, sink);
@ -268,7 +270,7 @@ Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath,
info.path = makeFixedOutputPath(recursive, hashAlgo, h, name); info.path = makeFixedOutputPath(recursive, hashAlgo, h, name);
if (repair || !isValidPath(info.path)) if (repair || !isValidPath(info.path))
addToCache(info, sink.s); addToCache(info, *sink.s);
return info.path; return info.path;
} }
@ -283,7 +285,7 @@ Path BinaryCacheStore::addTextToStore(const string & name, const string & s,
if (repair || !isValidPath(info.path)) { if (repair || !isValidPath(info.path)) {
StringSink sink; StringSink sink;
dumpString(s, sink); dumpString(s, sink);
addToCache(info, sink.s); addToCache(info, *sink.s);
} }
return info.path; return info.path;
@ -313,7 +315,7 @@ void BinaryCacheStore::buildPaths(const PathSet & paths, BuildMode buildMode)
StringSink sink; StringSink sink;
dumpPath(storePath, sink); dumpPath(storePath, sink);
addToCache(info, sink.s); addToCache(info, *sink.s);
} }
} }
@ -352,8 +354,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor
StringSink sink; StringSink sink;
store->exportPath(storePath, false, sink); store->exportPath(storePath, false, sink);
// FIXME: gratuitous string copying. auto accessor = makeNarAccessor(sink.s);
auto accessor = makeNarAccessor(make_ref<std::string>(sink.s));
nars.emplace(storePath, accessor); nars.emplace(storePath, accessor);
return {accessor, restPath}; return {accessor, restPath};
} }
@ -412,12 +413,11 @@ Path BinaryCacheStore::importPath(Source & source, std::shared_ptr<FSAccessor> a
bool haveSignature = readInt(source) == 1; bool haveSignature = readInt(source) == 1;
assert(!haveSignature); assert(!haveSignature);
addToCache(info, tee.data); addToCache(info, *tee.data);
auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor); auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor);
if (accessor_) if (accessor_)
// FIXME: more gratuitous string copying accessor_->nars.emplace(info.path, makeNarAccessor(tee.data));
accessor_->nars.emplace(info.path, makeNarAccessor(make_ref<std::string>(tee.data)));
return info.path; return info.path;
} }

View file

@ -2009,7 +2009,7 @@ void DerivationGoal::startBuilder()
throw SysError(format("linking %1% to %2%") % p % i); throw SysError(format("linking %1% to %2%") % p % i);
StringSink sink; StringSink sink;
dumpPath(i, sink); dumpPath(i, sink);
StringSource source(sink.s); StringSource source(*sink.s);
restorePath(p, source); restorePath(p, source);
} }
} }
@ -2666,8 +2666,8 @@ void DerivationGoal::registerOutputs()
StringSink sink; StringSink sink;
dumpPath(actualPath, sink); dumpPath(actualPath, sink);
deletePath(actualPath); deletePath(actualPath);
sink.s = rewriteHashes(sink.s, rewritesFromTmp); sink.s = make_ref<std::string>(rewriteHashes(*sink.s, rewritesFromTmp));
StringSource source(sink.s); StringSource source(*sink.s);
restorePath(actualPath, source); restorePath(actualPath, source);
rewritten = true; rewritten = true;

View file

@ -1415,9 +1415,9 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath,
if (recursive) if (recursive)
dumpPath(srcPath, sink, filter); dumpPath(srcPath, sink, filter);
else else
sink.s = readFile(srcPath); sink.s = make_ref<std::string>(readFile(srcPath));
return addToStoreFromDump(sink.s, name, recursive, hashAlgo, repair); return addToStoreFromDump(*sink.s, name, recursive, hashAlgo, repair);
} }
@ -1442,14 +1442,14 @@ Path LocalStore::addTextToStore(const string & name, const string & s,
StringSink sink; StringSink sink;
dumpString(s, sink); dumpString(s, sink);
auto hash = hashString(htSHA256, sink.s); auto hash = hashString(htSHA256, *sink.s);
optimisePath(dstPath); optimisePath(dstPath);
ValidPathInfo info; ValidPathInfo info;
info.path = dstPath; info.path = dstPath;
info.narHash = hash; info.narHash = hash;
info.narSize = sink.s.size(); info.narSize = sink.s->size();
info.references = references; info.references = references;
registerValidPath(info); registerValidPath(info);
} }

View file

@ -288,11 +288,11 @@ template PathSet readStrings(Source & source);
void StringSink::operator () (const unsigned char * data, size_t len) void StringSink::operator () (const unsigned char * data, size_t len)
{ {
static bool warned = false; static bool warned = false;
if (!warned && s.size() > threshold) { if (!warned && s->size() > threshold) {
warnLargeDump(); warnLargeDump();
warned = true; warned = true;
} }
s.append((const char *) data, len); s->append((const char *) data, len);
} }

View file

@ -110,7 +110,9 @@ private:
/* A sink that writes data to a string. */ /* A sink that writes data to a string. */
struct StringSink : Sink struct StringSink : Sink
{ {
string s; ref<std::string> s;
StringSink() : s(make_ref<std::string>()) { };
StringSink(ref<std::string> s) : s(s) { };
void operator () (const unsigned char * data, size_t len) override; void operator () (const unsigned char * data, size_t len) override;
}; };