Skip to content

Commit

Permalink
Merge pull request NixOS#47 from obsidiansystems/optional-self-modulo
Browse files Browse the repository at this point in the history
Fixup from git-with-refs branch
  • Loading branch information
Ericson2314 committed Jul 6, 2020
2 parents 637d233 + 50ca4af commit d258553
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 26 deletions.
3 changes: 3 additions & 0 deletions release-common.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ rec {
openssl sqlite
libarchive
boost

# PR: https://github.com/nlohmann/json/pull/2244
(nlohmann_json.overrideAttrs (_: rec {
version = "3.8.0post";
src = fetchFromGitHub {
Expand All @@ -70,6 +72,7 @@ rec {
sha256 = "12l7dsm2q45lkicwr4y9iv6b72z59683yg8mg0lcbacpaqh0566f";
};
}))

gmock
]
++ lib.optionals stdenv.isLinux [libseccomp utillinuxMinimal]
Expand Down
55 changes: 29 additions & 26 deletions src/libstore/ipfs-binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -603,44 +603,46 @@ class IPFSBinaryCacheStore : public Store
return putIpfsGitBlock(*sink.s);
}

std::unique_ptr<Source> getGitObject(std::string path, std::string hashPart)
std::unique_ptr<Source> getGitObject(std::string path, std::string hashPart, bool hasSelfReference)
{
return sinkToSource([path, hashPart, this](Sink & sink) {
return sinkToSource([path, hashPart, hasSelfReference, this](Sink & sink) {
StringSink sink2;
getIpfsBlock(path, sink2);

// unrewrite modulus
std::string offset;
std::string result = *sink2.s;
size_t i = result.size() - 1;
for (; i > 0; i--) {
char c = result.data()[i];
if (!(c >= '0' && c <= '9') && c != '|')
break;
if (c == '|') {
int pos = stoi(offset);
assert(pos > 0 && pos + hashPart.size() < i);
assert(std::string(result, pos, hashPart.size()) == std::string(hashPart.size(), 0));
std::copy(hashPart.begin(), hashPart.end(), result.begin() + pos);
offset = "";
} else
offset = c + offset;
if (hasSelfReference) {
// unrewrite modulus
std::string offset;
size_t i = result.size() - 1;
for (; i > 0; i--) {
char c = result.data()[i];
if (!(c >= '0' && c <= '9') && c != '|')
break;
if (c == '|') {
int pos = stoi(offset);
assert(pos > 0 && pos + hashPart.size() < i);
assert(std::string(result, pos, hashPart.size()) == std::string(hashPart.size(), 0));
std::copy(hashPart.begin(), hashPart.end(), result.begin() + pos);
offset = "";
} else
offset = c + offset;
}
result.erase(i + 1);
}
result.erase(i + 1);

sink(result);
});
}

void getGitEntry(ParseSink & sink, const Path & path,
const Path & realStoreDir, const Path & storeDir,
int perm, std::string name, Hash hash, std::string hashPart)
int perm, std::string name, Hash hash, std::string hashPart,
bool hasSelfReference)
{
auto source = getGitObject("/ipfs/f01781114" + hash.to_string(Base16, false), hashPart);
auto source = getGitObject("/ipfs/f01781114" + hash.to_string(Base16, false), hashPart, hasSelfReference);
parseGitWithPath(sink, *source, path + "/" + name, realStoreDir, storeDir,
[hashPart, this] (ParseSink & sink, const Path & path, const Path & realStoreDir, const Path & storeDir,
[hashPart, this, hasSelfReference] (ParseSink & sink, const Path & path, const Path & realStoreDir, const Path & storeDir,
int perm, std::string name, Hash hash) {
getGitEntry(sink, path, realStoreDir, storeDir, perm, name, hash, hashPart);
getGitEntry(sink, path, realStoreDir, storeDir, perm, name, hash, hashPart, hasSelfReference);
}, perm);
}

Expand Down Expand Up @@ -783,11 +785,12 @@ class IPFSBinaryCacheStore : public Store
AutoDelete tmpDir(createTempDir(), true);
// FIXME this is wrong, just doing so it builds
auto storePath = bakeCaIfNeeded(storePathOrCA);
auto source = getGitObject("/ipfs/" + std::string(info->url, 7), std::string(storePath.hashPart()));
auto hasSelfReference = info->hasSelfReference;
auto source = getGitObject("/ipfs/" + std::string(info->url, 7), std::string(storePath.hashPart()), hasSelfReference);
restoreGit((Path) tmpDir + "/tmp", *source, storeDir, storeDir,
[this, storePath] (ParseSink & sink, const Path & path, const Path & realStoreDir, const Path & storeDir,
[this, storePath, hasSelfReference] (ParseSink & sink, const Path & path, const Path & realStoreDir, const Path & storeDir,
int perm, std::string name, Hash hash) {
getGitEntry(sink, path, realStoreDir, storeDir, perm, name, hash, std::string(storePath.hashPart()));
getGitEntry(sink, path, realStoreDir, storeDir, perm, name, hash, std::string(storePath.hashPart()), hasSelfReference);
});
dumpPath((Path) tmpDir + "/tmp", wrapperSink);
return;
Expand Down

0 comments on commit d258553

Please sign in to comment.