diff --git a/autoload.cpp b/autoload.cpp index 0222bacf4..639eeca3d 100644 --- a/autoload.cpp +++ b/autoload.cpp @@ -30,143 +30,6 @@ file_access_attempt_t access_file(const wcstring &path, int mode) { return result; } -/** A node in our LRU map */ -class file_access_node_t { -public: - file_access_node_t *prev, *next; - const wcstring path; - file_access_attempt_t attempt; - - file_access_node_t(const wcstring &pathVar) : path(pathVar) { } - - bool operator<(const file_access_node_t &other) const { return path < other.path; } -}; - -/* By default, things are stale after 60 seconds */ -const time_t kFishDefaultStalenessInterval = 60; - -access_tracker_t::access_tracker_t(time_t stale, int the_mode) : - node_count(0), - mouth(NULL), - stale_interval(stale), - mode(the_mode) -{ - VOMIT_ON_FAILURE(pthread_mutex_init(&lock, NULL)); -} - -access_tracker_t::~access_tracker_t() { - VOMIT_ON_FAILURE(pthread_mutex_destroy(&lock)); -} - -void access_tracker_t::vacuum_one_node(void) { - /* Removes the least recently used access */ - assert(mouth && mouth->prev != mouth); - - /* Remove us from the linked list */ - file_access_node_t *condemned_node = mouth->prev; - condemned_node->prev->next = condemned_node->next; - condemned_node->next->prev = condemned_node->prev; - - /* Remove us from the set */ - access_set.erase(condemned_node); - - /* Deleted */ - node_count--; - delete condemned_node; -} - -void access_tracker_t::promote_node(file_access_node_t *node) { - /* Promotes a node to the mouth, unless we're already there... */ - if (node == mouth) return; - - /* First unhook us */ - node->prev->next = node->next; - node->next->prev = node->prev; - - /* Now become the mouth */ - node->next = mouth; - node->prev = mouth->prev; - mouth = node; -} - -/* Return the node referenced by the given string, or NULL */ -file_access_node_t *access_tracker_t::while_locked_find_node(const wcstring &path) const { - file_access_node_t key(path); - access_set_t::iterator iter = access_set.find(&key); - return iter != access_set.end() ? *iter : NULL; -} - -file_access_attempt_t access_tracker_t::attempt_access(const wcstring& path) const { - return ::access_file(path, this->mode); -} - -bool access_tracker_t::access_file_only_cached(const wcstring &path, file_access_attempt_t &attempt) { - bool result = false; - - /* Lock our lock */ - scoped_lock locker(lock); - - /* Search for the node */ - file_access_node_t *node = while_locked_find_node(path); - if (node) { - promote_node(node); - attempt = node->attempt; - attempt.stale = (time(NULL) - node->attempt.last_checked > this->stale_interval); - result = true; - } - return result; -} - -file_access_attempt_t access_tracker_t::access_file(const wcstring &path) { - file_access_attempt_t result; - - /* Try just using our cache */ - if (access_file_only_cached(path, result) && ! result.stale) { - return result; - } - - /* Really access the file. Note we are not yet locked, and don't want to be, since this may be slow. */ - result = attempt_access(path); - - /* Take the lock so we can insert. */ - scoped_lock locker(lock); - - /* Maybe we had it cached and it was stale, or maybe someone else may have put it in the cache while we were unlocked */ - file_access_node_t *node = while_locked_find_node(path); - - if (node != NULL) { - /* Someone else put it in. Promote and overwrite it. */ - node->attempt = result; - promote_node(node); - } else { - /* We did not find this node. Add it. */ - file_access_node_t *node = new file_access_node_t(path); - node->attempt = result; - - /* Insert into the set */ - access_set.insert(node); - - /* Insert it into the linked list */ - if (mouth == NULL) { - /* One element circularly linked list! */ - mouth = node->next = node->prev = node; - } else { - /* Normal circularly linked list operation */ - node->next = mouth; - node->prev = mouth->prev; - mouth = node; - } - - /* We have one more node now */ - ++node_count; - - /* Clean up if we're over our limit */ - while (node_count > kLRULimit) - vacuum_one_node(); - } - return result; -} - lru_cache_impl_t::lru_cache_impl_t() : node_count(0), mouth(L"") { /* Hook up the mouth to itself: a one node circularly linked list */ mouth.prev = mouth.next = &mouth; diff --git a/autoload.h b/autoload.h index 96ea628d2..ca3d61cfb 100644 --- a/autoload.h +++ b/autoload.h @@ -12,8 +12,6 @@ #include #include "common.h" -extern const time_t kFishDefaultStalenessInterval; - /** A struct responsible for recording an attempt to access a file. */ struct file_access_attempt_t { time_t mod_time; /** The modification time of the file */ @@ -23,8 +21,6 @@ struct file_access_attempt_t { int error; /** If we could not access the file, the error code */ }; -class file_access_node_t; - /** A predicate to compare dereferenced pointers */ struct dereference_less_t { template @@ -33,45 +29,6 @@ struct dereference_less_t { file_access_attempt_t access_file(const wcstring &path, int mode); -/** A class responsible for tracking accesses to files, including auto-expiration. */ -class access_tracker_t { - private: - - file_access_node_t * while_locked_find_node(const wcstring &str) const; - void vacuum_one_node(void); - void promote_node(file_access_node_t *); - - file_access_attempt_t attempt_access(const wcstring& path) const; - - unsigned int node_count; - typedef std::set access_set_t; - access_set_t access_set; - file_access_node_t *mouth; - - /* Lock for thread safety */ - pthread_mutex_t lock; - - /** How long until a file access attempt is considered stale. */ - const time_t stale_interval; - - /** Mode for waccess calls */ - const int mode; - - public: - - /** Constructor, that takes a staleness interval */ - access_tracker_t(time_t stale, int the_mode); - - /** Destructor */ - ~access_tracker_t(); - - /** Attempt to access the given file, if the last cached access is stale. Caches and returns the access attempt. */ - file_access_attempt_t access_file(const wcstring &path); - - /** Returns whether there is a cached access (even if stale), without touching the disk; if the result is true, return by reference that access attempt. */ - bool access_file_only_cached(const wcstring &path, file_access_attempt_t &attempt); -}; - class lru_node_t { friend class lru_cache_impl_t; /** Our linked list pointer */