00001 // Filename: adaptiveLru.I 00002 // Created by: drose (03Sep08) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: AdaptiveLru::get_total_size 00018 // Access: Published 00019 // Description: Returns the total size of all objects currently 00020 // active on the LRU. 00021 //////////////////////////////////////////////////////////////////// 00022 INLINE size_t AdaptiveLru:: 00023 get_total_size() const { 00024 LightMutexHolder holder(_lock); 00025 return _total_size; 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: AdaptiveLru::get_max_size 00030 // Access: Published 00031 // Description: Returns the max size of all objects that are allowed 00032 // to be active on the LRU. 00033 //////////////////////////////////////////////////////////////////// 00034 INLINE size_t AdaptiveLru:: 00035 get_max_size() const { 00036 LightMutexHolder holder(_lock); 00037 return _max_size; 00038 } 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Function: AdaptiveLru::set_max_size 00042 // Access: Published 00043 // Description: Changes the max size of all objects that are allowed 00044 // to be active on the LRU. 00045 // 00046 // If the size is (size_t)-1, there is no limit. 00047 //////////////////////////////////////////////////////////////////// 00048 INLINE void AdaptiveLru:: 00049 set_max_size(size_t max_size) { 00050 LightMutexHolder holder(_lock); 00051 _max_size = max_size; 00052 if (_total_size > _max_size) { 00053 do_evict_to(_max_size, false); 00054 } 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: AdaptiveLru::consider_evict 00059 // Access: Published 00060 // Description: Evicts a sequence of objects if the queue is full. 00061 //////////////////////////////////////////////////////////////////// 00062 INLINE void AdaptiveLru:: 00063 consider_evict() { 00064 LightMutexHolder holder(_lock); 00065 if (_total_size > _max_size) { 00066 do_evict_to(_max_size, false); 00067 } 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: AdaptiveLru::evict_to 00072 // Access: Published 00073 // Description: Evicts a sequence of objects until the queue fits 00074 // within the indicated target size, regardless of its 00075 // normal max size. 00076 //////////////////////////////////////////////////////////////////// 00077 INLINE void AdaptiveLru:: 00078 evict_to(size_t target_size) { 00079 LightMutexHolder holder(_lock); 00080 if (_total_size > target_size) { 00081 do_evict_to(target_size, true); 00082 } 00083 } 00084 00085 //////////////////////////////////////////////////////////////////// 00086 // Function: AdaptiveLru::validate 00087 // Access: Published 00088 // Description: Checks that the LRU is internally self-consistent. 00089 // Returns true if successful, false if there is some 00090 // problem. 00091 //////////////////////////////////////////////////////////////////// 00092 INLINE bool AdaptiveLru:: 00093 validate() { 00094 LightMutexHolder holder(_lock); 00095 return do_validate(); 00096 } 00097 00098 //////////////////////////////////////////////////////////////////// 00099 // Function: AdaptiveLru::set_weight 00100 // Access: Published 00101 // Description: Specifies the weight value used to compute the 00102 // exponential moving average. 00103 //////////////////////////////////////////////////////////////////// 00104 INLINE void AdaptiveLru:: 00105 set_weight(PN_stdfloat weight) { 00106 _weight = weight; 00107 } 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: AdaptiveLru::get_weight 00111 // Access: Published 00112 // Description: Returns the weight value used to compute the 00113 // exponential moving average. 00114 //////////////////////////////////////////////////////////////////// 00115 INLINE PN_stdfloat AdaptiveLru:: 00116 get_weight() const { 00117 return _weight; 00118 } 00119 00120 //////////////////////////////////////////////////////////////////// 00121 // Function: AdaptiveLru::set_max_updates_per_frame 00122 // Access: Published 00123 // Description: Specifies the maximum number of pages the AdaptiveLru 00124 // will update each frame. This is a performance 00125 // optimization: keeping this number low limits the 00126 // impact of the AdaptiveLru's adaptive algorithm. 00127 //////////////////////////////////////////////////////////////////// 00128 INLINE void AdaptiveLru:: 00129 set_max_updates_per_frame(int max_updates_per_frame) { 00130 _max_updates_per_frame = max_updates_per_frame; 00131 } 00132 00133 //////////////////////////////////////////////////////////////////// 00134 // Function: AdaptiveLru::get_max_updates_per_frame 00135 // Access: Published 00136 // Description: Returns the maximum number of pages the AdaptiveLru 00137 // will update each frame. 00138 //////////////////////////////////////////////////////////////////// 00139 INLINE int AdaptiveLru:: 00140 get_max_updates_per_frame() const { 00141 return _max_updates_per_frame; 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: AdaptiveLru::calculate_exponential_moving_average 00146 // Access: Private 00147 // Description: 00148 //////////////////////////////////////////////////////////////////// 00149 INLINE PN_stdfloat AdaptiveLru:: 00150 calculate_exponential_moving_average(PN_stdfloat value, PN_stdfloat average) const { 00151 return ((value - average) * _weight) + average; 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: AdaptiveLruPage::enqueue_lru 00156 // Access: Published 00157 // Description: Returns the LRU that manages this page, or NULL if it 00158 // is not currently managed by any LRU. 00159 //////////////////////////////////////////////////////////////////// 00160 INLINE AdaptiveLru *AdaptiveLruPage:: 00161 get_lru() const { 00162 return _lru; 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: AdaptiveLruPage::dequeue_lru 00167 // Access: Published 00168 // Description: Removes the page from its AdaptiveLru. 00169 //////////////////////////////////////////////////////////////////// 00170 INLINE void AdaptiveLruPage:: 00171 dequeue_lru() { 00172 enqueue_lru(NULL); 00173 } 00174 00175 //////////////////////////////////////////////////////////////////// 00176 // Function: AdaptiveLruPage::mark_used_lru 00177 // Access: Published 00178 // Description: To be called when the page is used; this will move it 00179 // to the tail of the AdaptiveLru queue it is already on. 00180 // 00181 // This method is const because it's not technically 00182 // modifying the contents of the page itself. 00183 //////////////////////////////////////////////////////////////////// 00184 INLINE void AdaptiveLruPage:: 00185 mark_used_lru() const { 00186 if (_lru != (AdaptiveLru *)NULL) { 00187 ((AdaptiveLruPage *)this)->mark_used_lru(_lru); 00188 } 00189 } 00190 00191 //////////////////////////////////////////////////////////////////// 00192 // Function: AdaptiveLruPage::mark_used_lru 00193 // Access: Published 00194 // Description: To be called when the page is used; this will move it 00195 // to the tail of the specified AdaptiveLru queue. 00196 //////////////////////////////////////////////////////////////////// 00197 INLINE void AdaptiveLruPage:: 00198 mark_used_lru(AdaptiveLru *lru) { 00199 enqueue_lru(lru); 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: AdaptiveLruPage::get_lru_size 00204 // Access: Published 00205 // Description: Returns the size of this page as reported to the LRU, 00206 // presumably in bytes. 00207 //////////////////////////////////////////////////////////////////// 00208 INLINE size_t AdaptiveLruPage:: 00209 get_lru_size() const { 00210 return _lru_size; 00211 } 00212 00213 //////////////////////////////////////////////////////////////////// 00214 // Function: AdaptiveLruPage::set_lru_size 00215 // Access: Published 00216 // Description: Specifies the size of this page, presumably in bytes, 00217 // although any unit is possible. 00218 //////////////////////////////////////////////////////////////////// 00219 INLINE void AdaptiveLruPage:: 00220 set_lru_size(size_t lru_size) { 00221 if (_lru != (AdaptiveLru *)NULL) { 00222 LightMutexHolder holder(_lru->_lock); 00223 _lru->_total_size -= _lru_size; 00224 _lru->_total_size += lru_size; 00225 _lru_size = lru_size; 00226 } else { 00227 _lru_size = lru_size; 00228 } 00229 }