00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <ostream>
00034 #include "AddressCache.h"
00035 #include "KeyRange.h"
00036
00037
00038 namespace mace {
00039
00040 void AddressCacheEntry::print(std::ostream& out) const
00041 {
00042 out << "ACE{" << _id << " = [ " << start << " , " << end << " )}";
00043 }
00044
00045 void AddressCache::consistency()
00046 {
00047 uint64_t now = TimeUtil::timeu();
00048 cachemap::map_iterator iter = entries.mapIterator();
00049 while(iter.hasNext()) {
00050 AddressCacheEntry& ent = iter.next();
00051 if (now > ent.time + MAX_CACHE_LIFE) {
00052 #ifdef CACHE_TRACE
00053 Log::log("cache_trace") << "Nuking stale " << ent << Log::endl;;
00054 #endif
00055 iter.remove();
00056 }
00057 }
00058 return;
00059 }
00060
00061 void AddressCache::insert(const MaceKey& start, const MaceKey& end, const MaceKey& address)
00062 {
00063 consistency();
00064
00065
00066 cachemap::map_iterator iter = entries.mapIterator();
00067 while(iter.hasNext()) {
00068 AddressCacheEntry& ent = iter.next();
00069 if(KeyRange::containsKey(start, ent.start, ent.end) || KeyRange::containsKey(ent.start, start, end)) {
00070 #ifdef CACHE_TRACE
00071 Log::log("cache_trace") << "(Nuking) Overlapping mappings " << ent << Log::endl;
00072 #endif
00073 iter.remove();
00074 }
00075 }
00076
00077 if(entries.contains(address)) {
00078 AddressCacheEntry& ent = entries.get(address);
00079 if(ent.start != start || ent.end != end) {
00080 ent.start = start;
00081 ent.end = end;
00082 ent.time = TimeUtil::timeu();
00083 #ifdef CACHE_TRACE
00084 Log::log("cache_trace") << "Updating " << address << " = [ " << start << " , " << end << " )" << Log::endl;
00085 #endif
00086 return;
00087 }
00088 }
00089 if (!entries.space()) {
00090
00091 entries.erase(entries.leastScore<double>());
00092 }
00093 #ifdef CACHE_TRACE
00094 Log::log("cache_trace") << "Adding " << address << " = [ " << start << " , " << end << " )" << Log::endl;
00095 #endif
00096 entries.add(AddressCacheEntry(address, start, end));
00097 return;
00098 }
00099
00100 MaceKey AddressCache::query(const MaceKey& query)
00101 {
00102
00103
00104 consistency();
00105 cachemap::map_iterator iter = entries.mapIterator();
00106 while(iter.hasNext()) {
00107 AddressCacheEntry& ent = iter.next();
00108 if(KeyRange::containsKey(query, ent.start, ent.end)) {
00109 #ifdef CACHE_TRACE
00110 Log::log("cache_trace") << "Using mapping " << ent << Log::endl;
00111 #endif
00112 return ent.getId();
00113 }
00114 }
00115 return MaceKey::null;
00116 }
00117
00118 void AddressCache::remove(const MaceKey& address)
00119 {
00120 entries.erase(address);
00121 }
00122
00123 void AddressCache::verify(const MaceKey& hash, const MaceKey& address)
00124 {
00125 consistency();
00126 cachemap::map_iterator iter = entries.mapIterator();
00127 while(iter.hasNext()) {
00128 AddressCacheEntry& ent = iter.next();
00129 if(KeyRange::containsKey(hash, ent.start, ent.end)) {
00130 if(ent.getId() != address) {
00131 iter.remove();
00132 }
00133 return;
00134 }
00135 }
00136 }
00137
00138 }