Skip to content

Commit

Permalink
Added relative sandbox path support for index db files save and load
Browse files Browse the repository at this point in the history
rdm --sandbox-root=/path/to/mysb ...
Index db files will be saved using relative path by stripping
"/path/to/mysb". This enables copying index db files over to a
new sandbox without need to reindex.
  • Loading branch information
hfeng authored and Andersbakken committed May 18, 2016
1 parent 8abd9bd commit 9f6c20d
Show file tree
Hide file tree
Showing 16 changed files with 333 additions and 72 deletions.
32 changes: 29 additions & 3 deletions src/ClangIndexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "RTags.h"
#include "VisitFileMessage.h"
#include "VisitFileResponseMessage.h"
#include "Location.h"

const CXSourceLocation ClangIndexer::nullLocation = clang_getNullLocation();
const CXCursor ClangIndexer::nullCursor = clang_getNullCursor();
Expand Down Expand Up @@ -67,7 +68,7 @@ struct VerboseVisitorUserData {
};

Flags<Server::Option> ClangIndexer::sServerOpts;
Path ClangIndexer::sServerRoot;
Path ClangIndexer::sServerSandboxRoot;
ClangIndexer::ClangIndexer()
: mClangUnit(0), mIndex(0), mLastCursor(nullCursor), mLastCallExpr(nullCursor),
mVisitFileResponseMessageFileId(0), mVisitFileResponseMessageVisit(0), mParseDuration(0),
Expand Down Expand Up @@ -118,7 +119,7 @@ bool ClangIndexer::exec(const String &data)
deserializer >> connectAttempts;
deserializer >> niceValue;
deserializer >> sServerOpts;
deserializer >> sServerRoot;
deserializer >> sServerSandboxRoot;
deserializer >> mUnsavedFiles;
deserializer >> mDataDir;
deserializer >> mDebugLocations;
Expand Down Expand Up @@ -1735,6 +1736,24 @@ static inline Map<String, Set<Location> > convertTargets(const Map<Location, Map
return ret;
}

static void convertRelativePath(Map<String, Set<Location> > & usrs)
{
std::list<String> sbstrs;

for (auto & m : usrs) {
if (Location::containSandboxRoot(m.first)) {
sbstrs.push_back(m.first);
}
}
for (auto & n : sbstrs) {
auto it = usrs.find(n);
assert(it != usrs.end());
String srel = Location::replaceFullWithRelativePath(n);
std::swap(usrs[srel], it->second);
usrs.erase(it);
}
}

bool ClangIndexer::writeFiles(const Path &root, String &error)
{
for (const auto &unit : mUnits) {
Expand Down Expand Up @@ -1764,14 +1783,21 @@ bool ClangIndexer::writeFiles(const Path &root, String &error)
error = "Failed to write symbols";
return false;
}
if (!FileMap<String, Set<Location> >::write(unitRoot + "/targets", convertTargets(unit.second->targets), fileMapOpts)) {
Map<String, Set<Location> > tmpTargets = convertTargets(unit.second->targets);
// SBROOT
convertRelativePath(tmpTargets);
if (!FileMap<String, Set<Location> >::write(unitRoot + "/targets", tmpTargets, fileMapOpts)) {
error = "Failed to write targets";
return false;
}
// SBROOT
convertRelativePath(unit.second->usrs);
if (!FileMap<String, Set<Location> >::write(unitRoot + "/usrs", unit.second->usrs, fileMapOpts)) {
error = "Failed to write usrs";
return false;
}
// SBROOT
convertRelativePath(unit.second->symbolNames);
if (!FileMap<String, Set<Location> >::write(unitRoot + "/symnames", unit.second->symbolNames, fileMapOpts)) {
error = "Failed to write symbolNames";
return false;
Expand Down
9 changes: 7 additions & 2 deletions src/ClangIndexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ class ClangIndexer

bool exec(const String &data);
static Flags<Server::Option> serverOpts() { return sServerOpts; }
static const Path &serverRoot() { return sServerRoot; }
static const Path &serverSandboxRoot() { return sServerSandboxRoot; }
static void setServerSandboxRoot(const String & s)
{
sServerSandboxRoot = s;
}

private:
bool diagnose();
bool visit();
Expand Down Expand Up @@ -211,7 +216,7 @@ class ClangIndexer
List<CXCursor> mParents;

static Flags<Server::Option> sServerOpts;
static Path sServerRoot;
static Path sServerSandboxRoot;
};

#endif
9 changes: 7 additions & 2 deletions src/Diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,19 @@ struct Diagnostic

template <> inline Serializer &operator<<(Serializer &s, const Diagnostic &d)
{
s << static_cast<uint8_t>(d.type) << d.message << d.length << d.ranges << d.children;
// SBROOT
String tmessage = Location::replaceFullWithRelativePath(d.message);
s << static_cast<uint8_t>(d.type) << tmessage << d.length << d.ranges << d.children;
return s;
}

template <> inline Deserializer &operator>>(Deserializer &s, Diagnostic &d)
{
uint8_t type;
s >> type >> d.message >> d.length >> d.ranges >> d.children;
String tmessage;
s >> type >> tmessage >> d.length >> d.ranges >> d.children;
// SBROOT
d.message = Location::replaceRelativeWithFullPath(tmessage);
d.type = static_cast<Diagnostic::Type>(type);
return s;
}
Expand Down
2 changes: 1 addition & 1 deletion src/IndexerJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ String IndexerJob::encode() const
<< static_cast<uint32_t>(options.rpConnectAttempts)
<< static_cast<int32_t>(options.rpNiceValue)
<< options.options
<< options.root
<< options.sandboxRoot
<< unsavedFiles
<< options.dataDir
<< options.debugLocations;
Expand Down
6 changes: 6 additions & 0 deletions src/JobScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ void JobScheduler::startJobs()
debug() << "Starting process for" << jobId << node->job->source.key() << node->job.get();
List<String> arguments;
arguments << "--priority" << String::number(node->job->priority);

// SBROOT
if (!options.sandboxRoot.isEmpty()) {
arguments << "--sandbox-root" << options.sandboxRoot.constData();
}

for (int i=logLevel().toInt(); i>0; --i)
arguments << "-v";

Expand Down
84 changes: 84 additions & 0 deletions src/Location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "RTags.h"
#include "Server.h"
#include "Project.h"
#include "ClangIndexer.h"

Hash<Path, uint32_t> Location::sPathsToIds;
Hash<uint32_t, Path> Location::sIdsToPaths;
Expand Down Expand Up @@ -124,6 +125,89 @@ String Location::context(Flags<ToStringFlag> flags, Hash<Path, String> *cache) c
return ret;
}

const Path &Location::sandboxRoot()
{
if (Server::instance()) {
return Server::instance()->options().sandboxRoot;
} else {
return ClangIndexer::serverSandboxRoot();
}
}

const char *RELSBROOT = "[[SBROOT]]";
static inline bool pathStartWithRELSBROOT(const Path &path)
{
return (strncmp(path.c_str(), RELSBROOT, strlen(RELSBROOT)) == 0);
}

bool Location::containRelativePath(const String & str)
{
return (str.indexOf(RELSBROOT) != std::string::npos);
}

void Location::strPathToSbRoot(Path &path)
{
auto idx = path.indexOf(RELSBROOT);
if (idx != std::string::npos) {
path.replace(idx, strlen(RELSBROOT), Location::sandboxRoot());
}
}

bool Location::containSandboxRoot(const String & str)
{
if (Location::sandboxRoot().isEmpty()) return false;
return (str.indexOf(Location::sandboxRoot()) != std::string::npos);
}

String Location::replaceRelativeWithFullPath(const String & key)
{
if (!Location::sandboxRoot().isEmpty()) {
auto idx = key.indexOf(RELSBROOT);
if (idx != std::string::npos) {
String keyCpy = key;
keyCpy.replace(idx, strlen(RELSBROOT), Location::sandboxRoot());
return keyCpy;
}
}
return key;
}

String Location::replaceFullWithRelativePath(const String & key)
{
if (!Location::sandboxRoot().isEmpty()) {
auto idx = key.indexOf(Location::sandboxRoot());
if (idx != std::string::npos) {
String keyCpy = key;
keyCpy.replace(idx, Location::sandboxRoot().size(), RELSBROOT);
return keyCpy;
}
}
return key;
}

void Location::convertPathRelative(Path & path)
{
if (!path.isEmpty() && !pathStartWithRELSBROOT(path)) {
// assert(path.isAbsolute());
const Path &root = Location::sandboxRoot();
if (!root.isEmpty() && path.startsWith(root)) {
assert(root.endsWith('/'));
path.replace(0, root.size(), RELSBROOT);
}
}
}

void Location::convertPathFull(Path &path)
{
if (pathStartWithRELSBROOT(path)) {
const Path &root = Location::sandboxRoot();
if (!root.isEmpty()) {
assert(root.endsWith('/'));
path.replace(0, strlen(RELSBROOT), root.c_str());
}
}
}

void Location::saveFileIds()
{
assert(Server::instance());
Expand Down
13 changes: 13 additions & 0 deletions src/Location.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ class Location
return sIdsToPaths.size();
}

static const Path & sandboxRoot();

static void strPathToSbRoot(Path &path);

static void convertPathRelative(Path & path);
static void convertPathFull(Path &path);

static bool containRelativePath(const String & str);
static bool containSandboxRoot(const String & str);

static String replaceRelativeWithFullPath(const String & key);
static String replaceFullWithRelativePath(const String & key);

static inline uint32_t insertFile(const Path &path)
{
bool save = false;
Expand Down
41 changes: 35 additions & 6 deletions src/Project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,20 @@ bool Project::readSources(const Path &path, Sources &sources, Hash<Path, Compila
return true;
}

static void converVisitedFilesToRelativePath(Hash<uint32_t, Path> & visitedFiles)
{
for (auto & m : visitedFiles) {
Location::convertPathRelative(m.second);
}
}

static void converVisitedFilesToFullPath(Hash<uint32_t, Path> & visitedFiles)
{
for (auto & m : visitedFiles) {
Location::convertPathFull(m.second);
}
}

bool Project::init()
{
const Server::Options &options = Server::instance()->options();
Expand Down Expand Up @@ -340,6 +354,8 @@ bool Project::init()
{
std::lock_guard<std::mutex> lock(mMutex);
file >> mVisitedFiles;
// SBROOT
converVisitedFilesToFullPath(mVisitedFiles);
}
file >> mDiagnostics;
for (const auto &info : mCompilationDatabaseInfos)
Expand Down Expand Up @@ -740,6 +756,8 @@ bool Project::save()
}
{
std::lock_guard<std::mutex> lock(mMutex);
// SBROOT
converVisitedFilesToRelativePath(mVisitedFiles);
file << mVisitedFiles;
}
file << mDiagnostics;
Expand Down Expand Up @@ -1264,7 +1282,9 @@ void Project::findSymbols(const String &string,
}

for (int i=idx; i<count; ++i) {
const String &entry = symNames->keyAt(i);
// SBROOT
String tsymName = Location::replaceRelativeWithFullPath(symNames->keyAt(i));
const String &entry = tsymName;
// error() << i << count << entry;
SymbolMatchType type = Exact;
if (!string.isEmpty()) {
Expand Down Expand Up @@ -1501,7 +1521,9 @@ Set<Symbol> Project::findByUsr(const String &usr, uint32_t fileId, DependencyMod
auto usrs = openUsrs(file);
// error() << usrs << Location::path(file) << usr;
if (usrs) {
for (Location loc : usrs->value(usr)) {
// SBROOT
String tusr = Location::replaceFullWithRelativePath(usr);
for (Location loc : usrs->value(tusr)) {
// error() << "got a loc" << loc;
const Symbol c = findSymbol(loc);
if (!c.isNull())
Expand All @@ -1516,7 +1538,9 @@ Set<Symbol> Project::findByUsr(const String &usr, uint32_t fileId, DependencyMod
for (const auto &dep : mDependencies) {
auto usrs = openUsrs(dep.first);
if (usrs) {
for (Location loc : usrs->value(usr)) {
// SBROOT
String tusr = Location::replaceFullWithRelativePath(usr);
for (Location loc : usrs->value(tusr)) {
const Symbol c = findSymbol(loc);
if (!c.isNull())
ret.insert(c);
Expand Down Expand Up @@ -1547,7 +1571,9 @@ static Set<Symbol> findReferences(const Set<Symbol> &inputs,
// error() << "Looking at file" << Location::path(dep) << "for input" << input.location;
auto targets = project->openTargets(dep);
if (targets) {
const Set<Location> locations = targets->value(input.usr);
// SBROOT
String tusr = Location::replaceFullWithRelativePath(input.usr);
const Set<Location> locations = targets->value(tusr);
// error() << "Got locations for usr" << input.usr << locations;
for (const auto &loc : locations) {
auto sym = project->findSymbol(loc);
Expand Down Expand Up @@ -1708,8 +1734,11 @@ Set<String> Project::findTargetUsrs(Location loc)
if (targets) {
const int count = targets->count();
for (int i=0; i<count; ++i) {
if (targets->valueAt(i).contains(loc))
usrs.insert(targets->keyAt(i));
if (targets->valueAt(i).contains(loc)) {
// SBROOT
String ttarget = Location::replaceRelativeWithFullPath(targets->keyAt(i));
usrs.insert(ttarget);
}
}
}
return usrs;
Expand Down
16 changes: 7 additions & 9 deletions src/RTags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
namespace RTags {
void encodePath(Path &path)
{
const Path &root = Server::instance() ? Server::instance()->options().root : ClangIndexer::serverRoot();
if (!root.isEmpty() && path.startsWith(root)) {
path.replace(0, root.size(), "$/");
// SBROOT
if (!Location::sandboxRoot().isEmpty()) {
Location::convertPathRelative(path);
}
int size = path.size();
for (int i=0; i<size; ++i) {
Expand All @@ -66,13 +66,11 @@ void encodePath(Path &path)

void decodePath(Path &path)
{
int i = 0;
if (path.startsWith("$_")) {
const Path &root = Server::instance() ? Server::instance()->options().root : ClangIndexer::serverRoot();
assert(!root.isEmpty());
path.replace(0, 2, root);
i = root.size();
// SBROOT
if (!Location::sandboxRoot().isEmpty()) {
Location::strPathToSbRoot(path);
}
int i = 0;
int size = path.size();
while (i < size) {
char &ch = path[i];
Expand Down
Loading

0 comments on commit 9f6c20d

Please sign in to comment.