Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 125 lines (111 sloc) 4.419 kb
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
1 // Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>
15
16 #include <assert.h>
17 #include <stdio.h>
18
19 #include <map>
f581c5d Henner Zeller o Give recency cache LRU semantics.
authored
20 #include <vector>
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
21 #include <boost/thread/locks.hpp>
22 #include <boost/thread/mutex.hpp>
23
24 #include "file-handler.h"
25 #include "file-handler-cache.h"
c1a03f2 Henner Zeller o Needed convenient sub-second resolution time. Added CurrentTime()
authored
26 #include "util.h"
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
27
223f392 Henner Zeller o Have a separate HandlerStats object that contains relevant
authored
28 struct FileHandlerCache::Entry {
29 Entry(FileHandler *h) : handler(h), references(0), last_access(0) {}
30 FileHandler *const handler;
31 int references;
32 double last_access; // seconds since epoch, sub-second resolution.
33 };
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
34
35 FileHandler *FileHandlerCache::InsertPinned(const std::string &key,
36 FileHandler *handler) {
37 boost::lock_guard<boost::mutex> l(mutex_);
38 CacheMap::iterator ins
39 = cache_.insert(std::make_pair(key, (Entry*)NULL)).first;
223f392 Henner Zeller o Have a separate HandlerStats object that contains relevant
authored
40 if (ins->second == NULL) {
41 ins->second = new Entry(handler);
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
42 } else {
43 delete handler;
44 }
45 ++ins->second->references;
f581c5d Henner Zeller o Give recency cache LRU semantics.
authored
46 if (cache_.size() > max_size_) {
47 CleanupOldestUnreferenced_Locked();
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
48 }
a9d3e53 Henner Zeller o Found a project name: "Folve". Some renamings because of that.
authored
49 ins->second->last_access = folve::CurrentTime();
223f392 Henner Zeller o Have a separate HandlerStats object that contains relevant
authored
50 if (observer_) observer_->InsertHandlerEvent(ins->second->handler);
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
51 return ins->second->handler;
52 }
53
54 FileHandler *FileHandlerCache::FindAndPin(const std::string &key) {
55 boost::lock_guard<boost::mutex> l(mutex_);
56 CacheMap::iterator found = cache_.find(key);
57 if (found == cache_.end())
58 return NULL;
59 ++found->second->references;
a9d3e53 Henner Zeller o Found a project name: "Folve". Some renamings because of that.
authored
60 found->second->last_access = folve::CurrentTime();
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
61 return found->second->handler;
62 }
63
64 void FileHandlerCache::Unpin(const std::string &key) {
65 boost::lock_guard<boost::mutex> l(mutex_);
66 CacheMap::iterator found = cache_.find(key);
67 assert(found != cache_.end());
68 --found->second->references;
7c00d62 Henner Zeller o new version
authored
69 // If we are already beyond cache size, clean up as soon as we get idle.
70 if (found->second->references == 0 && cache_.size() > max_size_) {
71 Erase_Locked(found);
72 }
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
73 }
74
223f392 Henner Zeller o Have a separate HandlerStats object that contains relevant
authored
75 void FileHandlerCache::SetObserver(Observer *observer) {
76 assert(observer_ == NULL);
77 observer_ = observer;
78 }
79
80 void FileHandlerCache::GetStats(std::vector<HandlerStats> *stats) {
81 HandlerStats s;
6c6dedb Henner Zeller o Some readme tweaks and readability improvements.
authored
82 boost::lock_guard<boost::mutex> l(mutex_);
8d1fbe7 Henner Zeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
83 for (CacheMap::iterator it = cache_.begin(); it != cache_.end(); ++it) {
223f392 Henner Zeller o Have a separate HandlerStats object that contains relevant
authored
84 it->second->handler->GetHandlerStatus(&s);
85 s.status = ((it->second->references == 0)
86 ? HandlerStats::IDLE
87 : HandlerStats::OPEN);
88 s.last_access = it->second->last_access;
89 stats->push_back(s);
8d1fbe7 Henner Zeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
90 }
91 }
92
7c00d62 Henner Zeller o new version
authored
93 void FileHandlerCache::Erase_Locked(CacheMap::iterator &cache_it) {
94 if (observer_) observer_->RetireHandlerEvent(cache_it->second->handler);
95 delete cache_it->second->handler; // FileHandler
96 delete cache_it->second; // Entry
97 cache_.erase(cache_it);
98 }
99
6c6dedb Henner Zeller o Some readme tweaks and readability improvements.
authored
100 struct FileHandlerCache::CompareAge {
101 bool operator() (const CacheMap::iterator &a, const CacheMap::iterator &b) {
102 return a->second->last_access < b->second->last_access;
103 }
104 };
f581c5d Henner Zeller o Give recency cache LRU semantics.
authored
105 void FileHandlerCache::CleanupOldestUnreferenced_Locked() {
106 assert(cache_.size() > max_size_); // otherwise we shouldn't have been called
107 // While this iterating through the whole cache might look expensive,
108 // in practice we're talking about 3 elements here.
109 // If we had significantly more, e.g. broken clients that don't close files,
110 // we need to keep better track of age.
111 std::vector<CacheMap::iterator> for_removal;
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
112 for (CacheMap::iterator it = cache_.begin(); it != cache_.end(); ++it) {
6c6dedb Henner Zeller o Some readme tweaks and readability improvements.
authored
113 if (it->second->references == 0) for_removal.push_back(it);
f581c5d Henner Zeller o Give recency cache LRU semantics.
authored
114 }
115
116 const size_t to_erase_count = std::min(cache_.size() - max_size_,
117 for_removal.size());
118 CompareAge comparator;
119 std::sort(for_removal.begin(), for_removal.end(), comparator);
120 for (size_t i = 0; i < to_erase_count; ++i) {
7c00d62 Henner Zeller o new version
authored
121 Erase_Locked(for_removal[i]);
15b305a Henner Zeller o Build infrastructure to re-use file handler objects. Files seem to
authored
122 }
123 }
7c00d62 Henner Zeller o new version
authored
124
Something went wrong with that request. Please try again.