mirror of
https://github.com/textmate/textmate.git
synced 2026-04-28 03:00:34 -04:00
Introduce scm::ng::root_for_path
Also change SCM implementation so that it doesn’t use objects with automatic storage, as the objects may be accessed from threads, which may run after objects with automatic storage has been destroyed.
This commit is contained in:
@@ -72,8 +72,9 @@ _Iter prune_path_children (_Iter it, _Iter last)
|
||||
|
||||
+ (NSURL*)scmURLWithPath:(NSString*)aPath
|
||||
{
|
||||
if(scm::info_ptr info = scm::info([aPath fileSystemRepresentation]))
|
||||
return [NSURL URLWithString:[NSString stringWithCxxString:"scm://localhost" + encode::url_part(info->path(), "/") + "/"]];
|
||||
std::string root = scm::ng::root_for_path([aPath fileSystemRepresentation]);
|
||||
if(root != NULL_STR)
|
||||
return [NSURL URLWithString:[NSString stringWithCxxString:"scm://localhost" + encode::url_part(root, "/") + "/"]];
|
||||
return [NSURL fileURLWithPath:aPath];
|
||||
}
|
||||
|
||||
|
||||
@@ -220,27 +220,41 @@ namespace scm { namespace ng
|
||||
// = Other =
|
||||
// =========
|
||||
|
||||
static std::map<std::string, shared_info_weak_ptr> cache;
|
||||
|
||||
shared_info_ptr find_shared_info_for (std::string const& path)
|
||||
static std::map<std::string, shared_info_weak_ptr>& cache ()
|
||||
{
|
||||
static scm::driver_t* const drivers[] = { scm::git_driver(), scm::hg_driver(), scm::p4_driver(), scm::svn_driver() };
|
||||
static auto res = new std::map<std::string, shared_info_weak_ptr>;
|
||||
return *res;
|
||||
}
|
||||
|
||||
static dispatch_queue_t cache_access_queue ()
|
||||
{
|
||||
static dispatch_queue_t res = dispatch_queue_create("org.textmate.scm.info-cache", DISPATCH_QUEUE_SERIAL);
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::vector<driver_t*> const& drivers ()
|
||||
{
|
||||
static auto const res = new std::vector<driver_t*>{ scm::git_driver(), scm::hg_driver(), scm::p4_driver(), scm::svn_driver() };
|
||||
return *res;
|
||||
}
|
||||
|
||||
static shared_info_ptr find_shared_info_for (std::string const& path)
|
||||
{
|
||||
for(std::string cwd = path; cwd != "/"; cwd = path::parent(cwd))
|
||||
{
|
||||
auto it = cache.find(cwd);
|
||||
if(it != cache.end())
|
||||
auto it = cache().find(cwd);
|
||||
if(it != cache().end())
|
||||
{
|
||||
if(shared_info_ptr res = it->second.lock())
|
||||
return res;
|
||||
}
|
||||
|
||||
for(driver_t* driver : drivers)
|
||||
for(driver_t* driver : drivers())
|
||||
{
|
||||
if(driver && driver->has_info_for_directory(cwd))
|
||||
{
|
||||
shared_info_ptr res(new shared_info_t(cwd, driver));
|
||||
cache[cwd] = res;
|
||||
cache()[cwd] = res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -248,6 +262,36 @@ namespace scm { namespace ng
|
||||
return shared_info_ptr();
|
||||
}
|
||||
|
||||
std::string root_for_path (std::string const& path)
|
||||
{
|
||||
if(path == NULL_STR || path == "" || path[0] != '/')
|
||||
return NULL_STR;
|
||||
|
||||
__block std::string res = NULL_STR;
|
||||
dispatch_sync(cache_access_queue(), ^{
|
||||
for(std::string cwd = path; res == NULL_STR && cwd != "/"; cwd = path::parent(cwd))
|
||||
{
|
||||
auto it = cache().find(cwd);
|
||||
if(it != cache().end())
|
||||
{
|
||||
res = cwd;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(driver_t* driver : drivers())
|
||||
{
|
||||
if(driver && driver->has_info_for_directory(cwd))
|
||||
{
|
||||
res = cwd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
info_ptr info (std::string path)
|
||||
{
|
||||
if(path == NULL_STR || path == "" || path[0] != '/')
|
||||
@@ -255,11 +299,9 @@ namespace scm { namespace ng
|
||||
|
||||
info_ptr res(new info_t(path));
|
||||
|
||||
static dispatch_queue_t queue = dispatch_queue_create("org.textmate.scm.info-cache", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
dispatch_sync(queue, ^{
|
||||
auto it = cache.find(path);
|
||||
if(it != cache.end())
|
||||
dispatch_sync(cache_access_queue(), ^{
|
||||
auto it = cache().find(path);
|
||||
if(it != cache().end())
|
||||
{
|
||||
if(shared_info_ptr sharedInfo = it->second.lock())
|
||||
res->set_shared_info(sharedInfo);
|
||||
@@ -268,7 +310,7 @@ namespace scm { namespace ng
|
||||
|
||||
if(res->dry())
|
||||
{
|
||||
dispatch_async(queue, ^{
|
||||
dispatch_async(cache_access_queue(), ^{
|
||||
if(shared_info_ptr info = find_shared_info_for(path))
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace scm { namespace ng
|
||||
shared_info_ptr _shared_info;
|
||||
};
|
||||
|
||||
PUBLIC std::string root_for_path (std::string const& path);
|
||||
PUBLIC info_ptr info (std::string path);
|
||||
|
||||
} /* ng */ } /* scm */
|
||||
|
||||
Reference in New Issue
Block a user