cache.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_CONTAINER_CACHE_H)
00023 #define INCLUDED_CONTAINER_CACHE_H
00024
00025 #include <cstddef>
00026 #include "container/hashtable.h"
00027 #include "memory/allocator.h"
00028
00029 template<typename Type, typename Parameter>
00030 class DefaultCreationPolicy {
00031 public:
00032 Type* construct(const Parameter& parameter) {
00033 return New<Type>().scalar(parameter);
00034 }
00035 void destroy(Type* p) {
00036 Delete<Type>().scalar(p);
00037 }
00038 };
00039
00040 template<typename Type>
00041 class SharedValue {
00042 typedef Type value_type;
00043 typedef value_type* pointer;
00044 typedef value_type& reference;
00045
00046 std::size_t m_count;
00047 pointer m_value;
00048
00049 public:
00050 SharedValue()
00051 : m_count(0), m_value(0) {
00052 }
00053 ~SharedValue() {
00054 ASSERT_MESSAGE(m_count == 0 , "destroying a referenced object\n");
00055 }
00056 void set(pointer value) {
00057 m_value = value;
00058 }
00059 pointer get() {
00060 return m_value;
00061 }
00062 std::size_t increment() {
00063 return ++m_count;
00064 }
00065 std::size_t decrement() {
00066 ASSERT_MESSAGE(!empty(), "destroying a non-existent object\n");
00067 return --m_count;
00068 }
00069 std::size_t count() {
00070 return m_count;
00071 }
00072 bool empty() {
00073 return m_count == 0;
00074 }
00075 reference operator*() const {
00076 ASSERT_NOTNULL(m_value);
00077 return *m_value;
00078 }
00079 pointer operator->() const {
00080 return &(operator*());
00081 }
00082 };
00083
00084
00085
00093 template < typename Key, typename Cached, typename Hasher, typename KeyEqual = std::equal_to<Key>, typename CreationPolicy = DefaultCreationPolicy<Cached, Key> >
00094 class HashedCache : public CreationPolicy {
00095 typedef SharedValue<Cached> Element;
00096 typedef HashTable<Key, Element, Hasher, KeyEqual> map_type;
00097
00098 map_type m_map;
00099
00100 public:
00101 explicit HashedCache(const CreationPolicy& creation = CreationPolicy())
00102 : CreationPolicy(creation), m_map(256) {
00103 }
00104 ~HashedCache() {
00105 ASSERT_MESSAGE(empty(), "HashedCache::~HashedCache: not empty");
00106 }
00107
00108 typedef typename map_type::iterator iterator;
00109 typedef typename map_type::value_type value_type;
00110
00111 iterator begin() {
00112 return m_map.begin();
00113 }
00114 iterator end() {
00115 return m_map.end();
00116 }
00117
00118 bool empty() const {
00119 return m_map.empty();
00120 }
00121
00122 iterator find(const Key& key) {
00123 return m_map.find(key);
00124 }
00125
00126 void capture(iterator i) {
00127 (*i).value.increment();
00128 }
00129 void release(iterator i) {
00130 if ((*i).value.decrement() == 0) {
00131 CreationPolicy::destroy((*i).value.get());
00132 m_map.erase(i);
00133 }
00134 }
00135
00136 Element& capture(const Key& key) {
00137 iterator i = m_map.insert(key, Element());
00138 if ((*i).value.increment() == 1) {
00139 (*i).value.set(CreationPolicy::construct((*i).key));
00140 }
00141 return (*i).value;
00142 }
00143 void release(const Key& key) {
00144 iterator i = m_map.find(key);
00145 ASSERT_MESSAGE(i != m_map.end(), "releasing a non-existent object\n");
00146 release(i);
00147 }
00148
00149 void clear() {
00150 m_map.clear();
00151 }
00152 };
00153
00154
00155 #endif