00001 #include "asset.h" 00002 #include "bcsignals.h" 00003 #include "cachebase.h" 00004 #include "edl.h" 00005 #include "mutex.h" 00006 00007 #include <string.h> 00008 00009 00010 00011 00012 CacheItemBase::CacheItemBase() 00013 : ListItem<CacheItemBase>() 00014 { 00015 age = 0; 00016 asset_id = -1; 00017 path = 0; 00018 } 00019 00020 CacheItemBase::~CacheItemBase() 00021 { 00022 free(path); // path was allocated with strdup in FramceCache::put_frame() 00023 } 00024 00025 00026 00027 00028 int CacheItemBase::get_size() 00029 { 00030 return 0; 00031 } 00032 00033 00034 00035 00036 00037 CacheBase::CacheBase() 00038 : List<CacheItemBase>() 00039 { 00040 lock = new Mutex("CacheBase::lock"); 00041 current_item = 0; 00042 } 00043 00044 CacheBase::~CacheBase() 00045 { 00046 delete lock; 00047 } 00048 00049 00050 00051 int CacheBase::get_age() 00052 { 00053 return EDL::next_id(); 00054 } 00055 00056 00057 // Called when done with the item returned by get_. 00058 // Ignore if item was 0. 00059 void CacheBase::unlock() 00060 { 00061 lock->unlock(); 00062 } 00063 00064 void CacheBase::remove_all() 00065 { 00066 int total = 0; 00067 lock->lock("CacheBase::remove_all"); 00068 while(last) 00069 { 00070 delete last; 00071 total++; 00072 } 00073 current_item = 0; 00074 lock->unlock(); 00075 //printf("CacheBase::remove_all: removed %d entries\n", total); 00076 } 00077 00078 00079 void CacheBase::remove_asset(Asset *asset) 00080 { 00081 int total = 0; 00082 lock->lock("CacheBase::remove_id"); 00083 for(current_item = first; current_item; ) 00084 { 00085 if(current_item->path && !strcmp(current_item->path, asset->path) || 00086 current_item->asset_id == asset->id) 00087 { 00088 CacheItemBase *next = current_item->next; 00089 delete current_item; 00090 total++; 00091 current_item = next; 00092 } 00093 else 00094 current_item = current_item->next; 00095 } 00096 lock->unlock(); 00097 //printf("CacheBase::remove_asset: removed %d entries for %s\n", total, asset->path); 00098 } 00099 00100 int CacheBase::get_oldest() 00101 { 00102 int oldest = 0x7fffffff; 00103 lock->lock("CacheBase::get_oldest"); 00104 for(CacheItemBase *current = first; current; current = NEXT) 00105 { 00106 if(current->age < oldest) 00107 oldest = current->age; 00108 } 00109 lock->unlock(); 00110 return oldest; 00111 } 00112 00113 00114 00115 int CacheBase::delete_oldest() 00116 { 00117 int oldest = 0x7fffffff; 00118 CacheItemBase *oldest_item = 0; 00119 00120 lock->lock("CacheBase::delete_oldest"); 00121 for(CacheItemBase *current = first; current; current = NEXT) 00122 { 00123 if(current->age < oldest) 00124 { 00125 oldest = current->age; 00126 oldest_item = current; 00127 } 00128 } 00129 00130 if(oldest_item) 00131 { 00132 // Too much data to debug if audio. 00133 // printf("CacheBase::delete_oldest: deleted position=%lld %d bytes\n", 00134 // oldest_item->position, oldest_item->get_size()); 00135 delete oldest_item; 00136 if(current_item == oldest_item) current_item = 0; 00137 lock->unlock(); 00138 return 0; 00139 } 00140 00141 lock->unlock(); 00142 return 1; 00143 } 00144 00145 00146 int64_t CacheBase::get_memory_usage() 00147 { 00148 int64_t result = 0; 00149 lock->lock("CacheBase::get_memory_usage"); 00150 for(CacheItemBase *current = first; current; current = NEXT) 00151 { 00152 result += current->get_size(); 00153 } 00154 lock->unlock(); 00155 return result; 00156 } 00157 00158 void CacheBase::put_item(CacheItemBase *item) 00159 { 00160 // Get first position >= item 00161 if(!current_item) current_item = first; 00162 while(current_item && current_item->position < item->position) 00163 current_item = current_item->next; 00164 if(!current_item) current_item = last; 00165 while(current_item && current_item->position >= item->position) 00166 current_item = current_item->previous; 00167 if(!current_item) 00168 current_item = first; 00169 else 00170 current_item = current_item->next; 00171 00172 if(!current_item) 00173 { 00174 append(item); 00175 current_item = item; 00176 } 00177 else 00178 insert_before(current_item, item); 00179 } 00180 00181 // Get first item from list with matching position or 0 if none found. 00182 CacheItemBase* CacheBase::get_item(int64_t position) 00183 { 00184 if(!current_item) current_item = first; 00185 while(current_item && current_item->position < position) 00186 current_item = current_item->next; 00187 if(!current_item) current_item = last; 00188 while(current_item && current_item->position >= position) 00189 current_item = current_item->previous; 00190 if(!current_item) 00191 current_item = first; 00192 else 00193 if(current_item->next) 00194 current_item = current_item->next; 00195 if(!current_item || current_item->position != position) return 0; 00196 return current_item; 00197 } 00198 00199 00200 00201 00202
1.5.5