pdf_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 "pdf_pages_cache.h"
00028 #include "pdf_doc_controller.h"
00029
00030 namespace pdf
00031 {
00032
00033 PagesCache::PagesCache(void)
00034 : size_limit(0)
00035 , total_length(0)
00036 , pages()
00037 , cache_mutex()
00038 {
00039 }
00040
00041 PagesCache::~PagesCache(void)
00042 {
00043 clear();
00044 }
00045
00046 bool PagesCache::reset(const unsigned int size)
00047 {
00048 ScopeMutex m(&cache_mutex);
00049
00050 int real_size = static_cast<int>(size);
00051
00052 if (size_limit > static_cast<unsigned int>(real_size))
00053 {
00054
00055 while (total_length > real_size)
00056 {
00057 if (!remove_page())
00058 {
00059
00060 return false;
00061 }
00062 }
00063 }
00064
00065 size_limit = static_cast<unsigned int>(real_size);
00066 return true;
00067 }
00068
00069 unsigned int PagesCache::size()
00070 {
00071 ScopeMutex m(&cache_mutex);
00072 return size_limit;
00073 }
00074
00075 void PagesCache::clear()
00076 {
00077 ScopeMutex m(&cache_mutex);
00078
00079 PagesIter begin = pages.begin();
00080 PagesIter end = pages.end();
00081 PagesIter iter = begin;
00082 for(; iter != end; ++iter)
00083 {
00084 delete iter->second;
00085 }
00086 pages.clear();
00087 total_length = 0;
00088 }
00089
00090
00091 void PagesCache::add_page(PagePtr p)
00092 {
00093 ScopeMutex m(&cache_mutex);
00094
00095 pages[(*p)()] = p;
00096 }
00097
00098
00099
00100 bool PagesCache::make_enough_memory(const int page_num, const int length)
00101 {
00102 ScopeMutex m(&cache_mutex);
00103
00104 int sum = total_length + length;
00105 if (sum <= static_cast<int>(size_limit))
00106 {
00107 return true;
00108 }
00109
00110
00111
00112 unsigned int size = (size_limit >> 1);
00113 while (sum > static_cast<int>(size))
00114 {
00115 if (!remove_page(page_num))
00116 {
00117
00118
00119
00120 if ((total_length + length) <= static_cast<int>(size_limit))
00121 {
00122
00123
00124
00125 return true;
00126 }
00127 LOGPRINTF("Skip Page:%d", page_num);
00128 return false;
00129 }
00130 sum = total_length + length;
00131 }
00132
00133 return true;
00134 }
00135
00136 void PagesCache::clear_cached_bitmaps()
00137 {
00138 ScopeMutex m(&cache_mutex);
00139
00140 LOGPRINTF("Clear cached bitmaps due to out of memory\n\n");
00141 PagePtr page = 0;
00142 PagesIter iter = pages.begin();
00143 for (; iter != pages.end(); ++iter)
00144 {
00145 page = iter->second;
00146 if (page->get_bitmap() && !page->locked())
00147 {
00148 int delta = static_cast<int>(page->destroy());
00149
00150
00151 total_length -= delta;
00152 }
00153 }
00154 }
00155
00156 PagePtr PagesCache::get_page(const size_t idx)
00157 {
00158 ScopeMutex m(&cache_mutex);
00159
00160 PagePtr page = 0;
00161 PagesIter iter = pages.find(idx);
00162 if (iter != pages.end())
00163 {
00164 page = iter->second;
00165 }
00166 return page;
00167 }
00168
00169 void PagesCache::update_mem_usage(const int length)
00170 {
00171 ScopeMutex m(&cache_mutex);
00172 total_length += length;
00173
00174
00175
00176 }
00177
00178 bool PagesCache::remove_page(const int page_num)
00179 {
00180
00181 PagesIter begin = pages.begin();
00182 PagesIter end = pages.end();
00183 PagesIter iter = begin;
00184 PagesIter remove_iter = iter;
00185
00186 while(iter != end)
00187 {
00188
00189 if (*(iter->second) < *(remove_iter->second))
00190 {
00191 remove_iter = iter;
00192 }
00193 iter++;
00194 }
00195
00196 if (remove_iter->second->get_bitmap() && !remove_iter->second->locked())
00197 {
00198 if (page_num >= 0 &&
00199 (remove_iter->second == pages[page_num] ||
00200 compare_priority(remove_iter->second->get_page_num(),
00201 page_num,
00202 remove_iter->second->get_doc_controller()->get_prerender_policy())
00203 >= 0))
00204 {
00205
00206
00207 return false;
00208 }
00209
00210
00211
00212 int delta = static_cast<int>(remove_iter->second->destroy());
00213
00214
00215 total_length -= delta;
00216
00217 LOGPRINTF("Remove Cached Page:%d, Total Length:%d, Delta Length:%d"
00218 , remove_iter->second->get_page_num()
00219 , total_length
00220 , delta);
00221
00222 if (total_length < 0)
00223 {
00224
00225 total_length = 0;
00226 }
00227 }
00228 else if (!remove_iter->second->get_bitmap())
00229 {
00230 WARNPRINTF("No bitmap now");
00231 return false;
00232 }
00233 else
00234 {
00235 WARNPRINTF("Cannot remove the locked page %d"
00236 , remove_iter->second->get_page_num());
00237 return false;
00238 }
00239
00240 return true;
00241 }
00242
00243 }
00244