2016-08-23 01:45:06 +03:00
|
|
|
// treemanifest.h - c++ declarations of a tree manifest
|
|
|
|
//
|
|
|
|
// Copyright 2016 Facebook, Inc.
|
|
|
|
//
|
|
|
|
// This software may be used and distributed according to the terms of the
|
|
|
|
// GNU General Public License version 2 or any later version.
|
|
|
|
//
|
|
|
|
// no-check-code
|
|
|
|
|
|
|
|
#ifndef REMOTEFILELOG_TREEMANIFEST_H
|
|
|
|
#define REMOTEFILELOG_TREEMANIFEST_H
|
|
|
|
|
2016-08-30 02:19:52 +03:00
|
|
|
#include "pythonutil.h"
|
|
|
|
|
2016-08-23 01:45:06 +03:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "manifest_fetcher.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A single instance of a treemanifest.
|
|
|
|
*/
|
|
|
|
struct treemanifest {
|
|
|
|
// A reference to the store that is used to fetch new content
|
|
|
|
PythonObj store;
|
|
|
|
|
|
|
|
// The 20-byte root node of this manifest
|
2016-08-26 23:49:17 +03:00
|
|
|
std::string rootNode;
|
2016-08-23 01:45:06 +03:00
|
|
|
|
2016-08-26 23:49:17 +03:00
|
|
|
// The resolved Manifest node, if the root has already been resolved.
|
|
|
|
Manifest *rootManifest;
|
|
|
|
|
2016-08-26 23:49:17 +03:00
|
|
|
treemanifest(PythonObj store, std::string rootNode) :
|
2016-08-23 01:45:06 +03:00
|
|
|
store(store),
|
2016-08-26 23:49:17 +03:00
|
|
|
rootNode(rootNode),
|
|
|
|
rootManifest(NULL) {
|
2016-08-23 01:45:06 +03:00
|
|
|
}
|
2016-08-27 00:00:37 +03:00
|
|
|
|
|
|
|
~treemanifest();
|
2016-08-23 01:45:06 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents a single stack frame in an iteration of the contents of the tree.
|
|
|
|
*/
|
|
|
|
struct stackframe {
|
2016-08-23 01:47:16 +03:00
|
|
|
Manifest *manifest;
|
2016-08-23 01:45:06 +03:00
|
|
|
ManifestIterator iterator;
|
|
|
|
|
2016-08-23 01:47:16 +03:00
|
|
|
stackframe(Manifest *manifest) :
|
2016-08-23 01:45:06 +03:00
|
|
|
manifest(manifest),
|
|
|
|
iterator(manifest->getIterator()) {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A helper struct representing the state of an iterator recursing over a tree.
|
|
|
|
*/
|
|
|
|
struct fileiter {
|
|
|
|
ManifestFetcher fetcher; // Instance to fetch tree content
|
|
|
|
std::vector<stackframe> frames;
|
|
|
|
std::string path; // The fullpath for the top entry in the stack.
|
|
|
|
|
2016-08-30 02:19:52 +03:00
|
|
|
// If provided, the given matcher filters the results by path
|
|
|
|
PythonObj matcher;
|
|
|
|
|
2016-08-30 02:19:52 +03:00
|
|
|
fileiter(treemanifest &tm) :
|
|
|
|
fetcher(tm.store) {
|
|
|
|
if (tm.rootManifest == NULL) {
|
|
|
|
tm.rootManifest = this->fetcher.get(NULL, 0, tm.rootNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->frames.push_back(stackframe(tm.rootManifest));
|
|
|
|
this->path.reserve(1024);
|
2016-08-23 01:45:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fileiter(const fileiter &old) :
|
|
|
|
fetcher(old.fetcher),
|
|
|
|
frames(old.frames),
|
|
|
|
path(old.path) {
|
|
|
|
}
|
|
|
|
|
|
|
|
fileiter& operator=(const fileiter &other) {
|
|
|
|
this->fetcher = other.fetcher;
|
|
|
|
this->frames = other.frames;
|
|
|
|
this->path = other.path;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class PathIterator {
|
|
|
|
private:
|
|
|
|
std::string path;
|
|
|
|
size_t position;
|
|
|
|
public:
|
|
|
|
PathIterator(std::string path) {
|
|
|
|
this->path = path;
|
|
|
|
this->position = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool next(char const ** word, size_t *wordlen) {
|
|
|
|
if (this->isfinished()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*word = this->path.c_str() + this->position;
|
|
|
|
size_t slashoffset = this->path.find('/', this->position);
|
|
|
|
if (slashoffset == std::string::npos) {
|
|
|
|
*wordlen = this->path.length() - this->position;
|
|
|
|
} else {
|
|
|
|
*wordlen = slashoffset - this->position;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->position += *wordlen + 1;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isfinished() {
|
|
|
|
return this->position >= this->path.length();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
extern void _treemanifest_find(
|
|
|
|
const std::string &filename,
|
|
|
|
const std::string &rootnode,
|
2016-08-26 23:49:17 +03:00
|
|
|
Manifest **cachedlookup,
|
2016-08-23 01:45:06 +03:00
|
|
|
const ManifestFetcher &fetcher,
|
|
|
|
std::string *resultnode, char *resultflag);
|
|
|
|
|
|
|
|
#endif //REMOTEFILELOG_TREEMANIFEST_H
|