images_pages_cache.cpp
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
00023
00024
00025
00026
00027 #include "images_pages_cache.h"
00028 #include "log.h"
00029
00030 namespace images
00031 {
00032
00033 PagesCache::PagesCache(void)
00034 : total_length(DEFAULT_MEMORY_LIMIT)
00035 , used_length(0)
00036 , pages()
00037 , cache_mutex(0)
00038 {
00039 cache_mutex = g_mutex_new();
00040 }
00041
00042 PagesCache::~PagesCache(void)
00043 {
00044 g_mutex_lock(cache_mutex);
00045 clear();
00046 g_mutex_unlock(cache_mutex);
00047 g_mutex_free(cache_mutex);
00048 }
00049
00050 bool PagesCache::set_memory_limit(const int bytes)
00051 {
00052 g_mutex_lock(cache_mutex);
00053
00054 if (total_length > static_cast<unsigned int>(bytes))
00055 {
00056
00057 while (used_length > static_cast<unsigned int>(bytes))
00058 {
00059 if (!remove_page())
00060 {
00061 g_mutex_unlock(cache_mutex);
00062 return false;
00063 }
00064 }
00065 }
00066
00067 total_length = static_cast<unsigned int>(bytes);
00068
00069 g_mutex_unlock(cache_mutex);
00070 return true;
00071 }
00072
00073 bool PagesCache::make_enough_memory(const gint64 length)
00074 {
00075 bool ok = true;
00076
00077 g_mutex_lock(cache_mutex);
00078 LOGPRINTF("used [%d] total [%d] request [%lld]", used_length, total_length, length);
00079
00080 while ( ok && length > static_cast<gint64>(total_length - used_length) )
00081 {
00082 if (!remove_page())
00083 {
00084
00085
00086
00087 ok = false;
00088 }
00089 }
00090
00091 g_mutex_unlock(cache_mutex);
00092 return ok;
00093 }
00094
00095 bool PagesCache::add_page(ImagePage * p)
00096 {
00097 if (!p) { return false; }
00098
00099 const int length = p->length();
00100
00101
00102 make_enough_memory( static_cast<gint64>(length) );
00103
00104
00105 g_mutex_lock(cache_mutex);
00106 pages[(*p)()] = p;
00107 used_length += length;
00108 g_mutex_unlock(cache_mutex);
00109
00110 return true;
00111 }
00112
00113 ImagePage * PagesCache::get_page(const size_t idx)
00114 {
00115 g_mutex_lock(cache_mutex);
00116
00117 ImagePage * p = 0;
00118 PagesIter iter = pages.find(idx);
00119 if (iter != pages.end())
00120 {
00121 p = iter->second;
00122 }
00123
00124 g_mutex_unlock(cache_mutex);
00125 return p;
00126 }
00127
00128 void PagesCache::lock(void)
00129 {
00130 g_mutex_lock(cache_mutex);
00131 }
00132
00133 void PagesCache::unlock(void)
00134 {
00135 g_mutex_unlock(cache_mutex);
00136 }
00137
00138 void PagesCache::clear(void)
00139 {
00140 PagesIter begin = pages.begin();
00141 PagesIter end = pages.end();
00142 PagesIter iter = begin;
00143 for(; iter != end; ++iter)
00144 {
00145 delete iter->second;
00146 }
00147 pages.clear();
00148 used_length = 0;
00149 }
00150
00151 bool PagesCache::remove_page(void)
00152 {
00153 if (pages.empty())
00154 {
00155 return false;
00156 }
00157
00158
00159 PagesIter begin = pages.begin();
00160 PagesIter end = pages.end();
00161 PagesIter iter = begin;
00162 PagesIter remove_iter = iter;
00163
00164 while(iter != end)
00165 {
00166 if ((*iter->second) < (*remove_iter->second))
00167 {
00168 remove_iter = iter;
00169 }
00170 iter++;
00171 }
00172
00173 bool b_removed;
00174 if (!remove_iter->second->get_in_use_flag())
00175 {
00176
00177 used_length -= remove_iter->second->length();
00178
00179
00180 delete remove_iter->second;
00181 pages.erase(remove_iter);
00182
00183 b_removed = true;
00184 }
00185 else
00186 {
00187 b_removed = false;
00188 }
00189
00190 return b_removed;
00191 }
00192 };
00193
00194