mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
[ctree] get rid of manifestkey
Summary: Directly pass in the path + len and the node. Note that the path is now a char* + len, because this allows us to use the path in treemanifest_find directly, rather than to construct a new path. Test Plan: run existing perftest without crash. Reviewers: #fastmanifest, durham Reviewed By: durham Subscribers: mitrandir Differential Revision: https://phabricator.intern.facebook.com/D3738280 Signature: t1:3738280:1471890923:c13283f1c61dc020ba1918ee9b25c24dfd2fc19b
This commit is contained in:
parent
8205ab233f
commit
e953a3cc27
@ -95,11 +95,11 @@ void ManifestEntry::appendtopath(std::string &path) {
|
||||
}
|
||||
}
|
||||
|
||||
Manifest *ManifestEntry::get_manifest(ManifestFetcher fetcher, std::string &path) {
|
||||
Manifest *ManifestEntry::get_manifest(
|
||||
ManifestFetcher fetcher, const char *path, size_t pathlen) {
|
||||
if (this->resolved == NULL) {
|
||||
std::string binnode = binfromhex(node);
|
||||
manifestkey key(&path, &binnode);
|
||||
this->resolved = fetcher.get(key);
|
||||
this->resolved = fetcher.get(path, pathlen, binnode);
|
||||
}
|
||||
|
||||
return this->resolved;
|
||||
|
@ -53,7 +53,8 @@ class ManifestEntry {
|
||||
|
||||
void appendtopath(std::string &path);
|
||||
|
||||
Manifest *get_manifest(ManifestFetcher fetcher, std::string &path);
|
||||
Manifest *get_manifest(
|
||||
ManifestFetcher fetcher, const char *path, size_t pathlen);
|
||||
};
|
||||
|
||||
#endif //REMOTEFILELOG_MANIFEST_ENTRY_H
|
||||
|
@ -17,10 +17,12 @@ ManifestFetcher::ManifestFetcher(PythonObj &store) :
|
||||
* Fetches the Manifest from the store for the provided manifest key.
|
||||
* Returns the manifest if found, or throws an exception if not found.
|
||||
*/
|
||||
Manifest *ManifestFetcher::get(const manifestkey &key) const {
|
||||
Manifest *ManifestFetcher::get(
|
||||
const char *path, size_t pathlen,
|
||||
std::string &node) const {
|
||||
PythonObj arglist = Py_BuildValue("s#s#",
|
||||
key.path->c_str(), (Py_ssize_t)key.path->size(),
|
||||
key.node->c_str(), (Py_ssize_t)key.node->size());
|
||||
path, (Py_ssize_t) pathlen,
|
||||
node.c_str(), (Py_ssize_t)node.size());
|
||||
|
||||
PyObject *result = PyEval_CallObject(this->_get, arglist);
|
||||
|
||||
@ -29,7 +31,8 @@ Manifest *ManifestFetcher::get(const manifestkey &key) const {
|
||||
throw pyexception();
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_RuntimeError, "unable to find tree '%s:...'", key.path->c_str());
|
||||
PyErr_Format(PyExc_RuntimeError,
|
||||
"unable to find tree '%.*s:...'", (int) pathlen, path);
|
||||
throw pyexception();
|
||||
}
|
||||
|
||||
|
@ -17,19 +17,6 @@ class ManifestFetcher;
|
||||
#include "manifest.h"
|
||||
#include "pythonutil.h"
|
||||
|
||||
/**
|
||||
* A key which can be used to look up a manifest.
|
||||
*/
|
||||
struct manifestkey {
|
||||
std::string *path;
|
||||
std::string *node;
|
||||
|
||||
manifestkey(std::string *path, std::string *node) :
|
||||
path(path),
|
||||
node(node) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class used to obtain Manifests, given a path and node.
|
||||
*/
|
||||
@ -43,7 +30,9 @@ class ManifestFetcher {
|
||||
* Fetches the Manifest from the store for the provided manifest key.
|
||||
* Returns the manifest if found, or throws an exception if not found.
|
||||
*/
|
||||
Manifest *get(const manifestkey &key) const;
|
||||
Manifest *get(
|
||||
const char *path, size_t pathlen,
|
||||
std::string &node) const;
|
||||
};
|
||||
|
||||
#endif //REMOTEFILELOG_MANIFEST_FETCHER_H
|
||||
|
@ -156,8 +156,7 @@ static PyObject *treemanifest_getkeysiter(py_treemanifest *self) {
|
||||
|
||||
// Grab the root node's data and prep the iterator
|
||||
std::string rootpath;
|
||||
Manifest *root = fetcher.get(
|
||||
manifestkey(&rootpath, &self->tm.node));
|
||||
Manifest *root = fetcher.get(NULL, 0, self->tm.node);
|
||||
|
||||
// TODO: root manifest should be stored in the treemanifest object and
|
||||
// used if it's available.
|
||||
@ -304,7 +303,8 @@ static void treemanifest_diffrecurse(
|
||||
// selfentry should be processed first and only exists in self
|
||||
selfentry.appendtopath(*path);
|
||||
if (selfentry.isdirectory()) {
|
||||
Manifest *selfchildmanifest = selfentry.get_manifest(fetcher, *path);
|
||||
Manifest *selfchildmanifest = selfentry.get_manifest(
|
||||
fetcher, path->c_str(), path->size());
|
||||
treemanifest_diffrecurse(selfchildmanifest, NULL, path, diff, fetcher);
|
||||
} else {
|
||||
DiffEntry entry(&selfbinnode, selfentry.flag, NULL, NULL);
|
||||
@ -315,7 +315,8 @@ static void treemanifest_diffrecurse(
|
||||
// otherentry should be processed first and only exists in other
|
||||
otherentry.appendtopath(*path);
|
||||
if (otherentry.isdirectory()) {
|
||||
Manifest *otherchildmanifest = otherentry.get_manifest(fetcher, *path);
|
||||
Manifest *otherchildmanifest = otherentry.get_manifest(
|
||||
fetcher, path->c_str(), path->size());
|
||||
treemanifest_diffrecurse(NULL, otherchildmanifest, path, diff, fetcher);
|
||||
} else {
|
||||
DiffEntry entry(NULL, NULL, &otherbinnode, otherentry.flag);
|
||||
@ -329,10 +330,12 @@ static void treemanifest_diffrecurse(
|
||||
selfentry.appendtopath(*path);
|
||||
|
||||
if (selfbinnode != otherbinnode) {
|
||||
manifestkey selfkey(path, &selfbinnode);
|
||||
manifestkey otherkey(path, &otherbinnode);
|
||||
Manifest *selfchildmanifest = fetcher.get(selfkey);
|
||||
Manifest *otherchildmanifest = fetcher.get(otherkey);
|
||||
Manifest *selfchildmanifest = fetcher.get(
|
||||
path->c_str(), path->size(),
|
||||
selfbinnode);
|
||||
Manifest *otherchildmanifest = fetcher.get(
|
||||
path->c_str(), path->size(),
|
||||
otherbinnode);
|
||||
|
||||
treemanifest_diffrecurse(
|
||||
selfchildmanifest,
|
||||
@ -350,8 +353,9 @@ static void treemanifest_diffrecurse(
|
||||
entry.addtodiff(diff, *path);
|
||||
|
||||
path->append(1, '/');
|
||||
manifestkey selfkey(path, &selfbinnode);
|
||||
Manifest *selfchildmanifest = fetcher.get(selfkey);
|
||||
Manifest *selfchildmanifest = fetcher.get(
|
||||
path->c_str(), path->size(),
|
||||
selfbinnode);
|
||||
treemanifest_diffrecurse(selfchildmanifest, NULL, path, diff, fetcher);
|
||||
|
||||
selfiter.next(&selfentry);
|
||||
@ -363,8 +367,10 @@ static void treemanifest_diffrecurse(
|
||||
entry.addtodiff(diff, *path);
|
||||
|
||||
path->append(1, '/');
|
||||
manifestkey otherkey(path, &otherbinnode);
|
||||
Manifest *otherchildmanifest = fetcher.get(otherkey);
|
||||
Manifest *otherchildmanifest = fetcher.get(
|
||||
path->c_str(), path->size(),
|
||||
otherbinnode
|
||||
);
|
||||
treemanifest_diffrecurse(NULL, otherchildmanifest, path, diff, fetcher);
|
||||
|
||||
selfiter.next(&selfentry);
|
||||
@ -407,10 +413,14 @@ static PyObject *treemanifest_diff(PyObject *o, PyObject *args) {
|
||||
std::string path;
|
||||
try {
|
||||
path.reserve(1024);
|
||||
manifestkey selfkey(&path, &self->tm.node);
|
||||
manifestkey otherkey(&path, &other->tm.node);
|
||||
Manifest *selfmanifest = fetcher.get(selfkey);
|
||||
Manifest *othermanifest = fetcher.get(otherkey);
|
||||
Manifest *selfmanifest = fetcher.get(
|
||||
path.c_str(), path.size(),
|
||||
self->tm.node
|
||||
);
|
||||
Manifest *othermanifest = fetcher.get(
|
||||
path.c_str(), path.size(),
|
||||
other->tm.node
|
||||
);
|
||||
treemanifest_diffrecurse(
|
||||
selfmanifest, othermanifest, &path, results, fetcher);
|
||||
} catch (const pyexception &ex) {
|
||||
@ -424,13 +434,13 @@ static PyObject *treemanifest_diff(PyObject *o, PyObject *args) {
|
||||
return results.returnval();
|
||||
}
|
||||
|
||||
static void _treemanifest_find(const std::string &filename, const manifestkey &root,
|
||||
const ManifestFetcher &fetcher, std::string *resultnode, char *resultflag) {
|
||||
// Pre-allocate our curkey so we can reuse it for each iteration
|
||||
std::string curname(*root.path);
|
||||
curname.reserve(1024);
|
||||
std::string curnode(*root.node);
|
||||
manifestkey curkey(&curname, &curnode);
|
||||
static void _treemanifest_find(
|
||||
const std::string &filename,
|
||||
const std::string &rootnode,
|
||||
const ManifestFetcher &fetcher,
|
||||
std::string *resultnode, char *resultflag) {
|
||||
size_t curpathlen = 0;
|
||||
std::string curnode(rootnode);
|
||||
|
||||
// Loop over the parts of the query filename
|
||||
PathIterator pathiter(filename);
|
||||
@ -438,7 +448,7 @@ static void _treemanifest_find(const std::string &filename, const manifestkey &r
|
||||
size_t wordlen;
|
||||
while (pathiter.next(&word, &wordlen)) {
|
||||
// Obtain the raw data for this directory
|
||||
Manifest *manifest = fetcher.get(curkey);
|
||||
Manifest *manifest = fetcher.get(filename.c_str(), curpathlen, curnode);
|
||||
|
||||
// TODO: need to attach this manifest to the parent Manifest object.
|
||||
|
||||
@ -470,11 +480,10 @@ static void _treemanifest_find(const std::string &filename, const manifestkey &r
|
||||
}
|
||||
|
||||
// If there's more in the query, either recurse or give up
|
||||
size_t nextpathlen = curkey.path->length() + wordlen + 1;
|
||||
if (entry.isdirectory() && filename.length() > nextpathlen) {
|
||||
// Get the fullpath of the current directory/file we're searching in
|
||||
curkey.path->assign(filename, 0, nextpathlen);
|
||||
curkey.node->assign(binfromhex(entry.node));
|
||||
curpathlen = curpathlen + wordlen + 1;
|
||||
if (entry.isdirectory() && filename.length() > curpathlen) {
|
||||
curnode.erase();
|
||||
curnode.append(binfromhex(entry.node));
|
||||
recurse = true;
|
||||
break;
|
||||
} else {
|
||||
@ -512,9 +521,11 @@ static PyObject *treemanifest_find(PyObject *o, PyObject *args) {
|
||||
char resultflag;
|
||||
try {
|
||||
std::string rootpath;
|
||||
manifestkey rootkey(&rootpath, &self->tm.node);
|
||||
_treemanifest_find(std::string(filename, filenamelen), rootkey, fetcher,
|
||||
&resultnode, &resultflag);
|
||||
_treemanifest_find(
|
||||
std::string(filename, filenamelen),
|
||||
self->tm.node,
|
||||
fetcher,
|
||||
&resultnode, &resultflag);
|
||||
} catch (const pyexception &ex) {
|
||||
return NULL;
|
||||
}
|
||||
@ -637,7 +648,8 @@ static PyObject *fileiter_iterentriesnext(py_fileiter *self) {
|
||||
iter.path.append(entry.filename, entry.filenamelen);
|
||||
iter.path.append(1, '/');
|
||||
|
||||
Manifest *submanifest = entry.get_manifest(iter.fetcher, iter.path);
|
||||
Manifest *submanifest = entry.get_manifest(iter.fetcher,
|
||||
iter.path.c_str(), iter.path.size());
|
||||
|
||||
// TODO: memory cleanup here is probably broken.
|
||||
iter.frames.push_back(stackframe(submanifest));
|
||||
|
Loading…
Reference in New Issue
Block a user