r1014: Enable horizontal scrolling with the mouse wheel by pressing Ctrl.
[cinelerra_cv/ct.git] / cinelerra / cachebase.C
blob97df7ff04c8188c0f69f0725a3a11c0fa38cd099
1 #include "asset.h"
2 #include "bcsignals.h"
3 #include "cachebase.h"
4 #include "edl.h"
5 #include "mutex.h"
7 #include <string.h>
12 CacheItemBase::CacheItemBase()
13  : ListItem<CacheItemBase>()
15         age = 0;
16         asset_id = -1;
17         path = 0;
20 CacheItemBase::~CacheItemBase()
22         free(path); // path was allocated with strdup in FramceCache::put_frame()
28 int CacheItemBase::get_size()
30         return 0;
37 CacheBase::CacheBase()
38  : List<CacheItemBase>()
40         lock = new Mutex("CacheBase::lock");
41         current_item = 0;
44 CacheBase::~CacheBase()
46         delete lock;
51 int CacheBase::get_age()
53         return EDL::next_id();
57 // Called when done with the item returned by get_.
58 // Ignore if item was 0.
59 void CacheBase::unlock()
61     lock->unlock();
64 void CacheBase::remove_all()
66         int total = 0;
67         lock->lock("CacheBase::remove_all");
68         while(last)
69         {
70                 delete last;
71                 total++;
72         }
73         current_item = 0;
74         lock->unlock();
75 //printf("CacheBase::remove_all: removed %d entries\n", total);
79 void CacheBase::remove_asset(Asset *asset)
81         int total = 0;
82         lock->lock("CacheBase::remove_id");
83         for(current_item = first; current_item; )
84         {
85                 if(current_item->path && !strcmp(current_item->path, asset->path) ||
86                         current_item->asset_id == asset->id)
87                 {
88                         CacheItemBase *next = current_item->next;
89                         delete current_item;
90                         total++;
91                         current_item = next;
92                 }
93                 else
94                         current_item = current_item->next;
95         }
96         lock->unlock();
97 //printf("CacheBase::remove_asset: removed %d entries for %s\n", total, asset->path);
100 int CacheBase::get_oldest()
102         int oldest = 0x7fffffff;
103         lock->lock("CacheBase::get_oldest");
104         for(CacheItemBase *current = first; current; current = NEXT)
105         {
106                 if(current->age < oldest)
107                         oldest = current->age;
108         }
109         lock->unlock();
110         return oldest;
115 int CacheBase::delete_oldest()
117         int oldest = 0x7fffffff;
118         CacheItemBase *oldest_item = 0;
120         lock->lock("CacheBase::delete_oldest");
121         for(CacheItemBase *current = first; current; current = NEXT)
122         {
123                 if(current->age < oldest)
124                 {
125                         oldest = current->age;
126                         oldest_item = current;
127                 }
128         }
130         if(oldest_item)
131         {
132 // Too much data to debug if audio.
133 // printf("CacheBase::delete_oldest: deleted position=%lld %d bytes\n", 
134 // oldest_item->position, oldest_item->get_size());
135                 delete oldest_item;
136                 if(current_item == oldest_item) current_item = 0;
137                 lock->unlock();
138                 return 0;
139         }
141         lock->unlock();
142         return 1;
146 int64_t CacheBase::get_memory_usage()
148         int64_t result = 0;
149         lock->lock("CacheBase::get_memory_usage");
150         for(CacheItemBase *current = first; current; current = NEXT)
151         {
152                 result += current->get_size();
153         }
154         lock->unlock();
155         return result;
158 void CacheBase::put_item(CacheItemBase *item)
160 // Get first position >= item
161         if(!current_item) current_item = first;
162         while(current_item && current_item->position < item->position)
163                 current_item = current_item->next;
164         if(!current_item) current_item = last;
165         while(current_item && current_item->position >= item->position)
166                 current_item = current_item->previous;
167         if(!current_item) 
168                 current_item = first;
169         else
170                 current_item = current_item->next;
172         if(!current_item)
173         {
174                 append(item);
175                 current_item = item;
176         }
177         else
178                 insert_before(current_item, item);
181 // Get first item from list with matching position or 0 if none found.
182 CacheItemBase* CacheBase::get_item(int64_t position)
184         if(!current_item) current_item = first;
185         while(current_item && current_item->position < position)
186                 current_item = current_item->next;
187         if(!current_item) current_item = last;
188         while(current_item && current_item->position >= position)
189                 current_item = current_item->previous;
190         if(!current_item)
191                 current_item = first;
192         else
193         if(current_item->next)
194                 current_item = current_item->next;
195         if(!current_item || current_item->position != position) return 0;
196         return current_item;