X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcachebase.C;fp=cinelerra-5.1%2Fcinelerra%2Fcachebase.C;h=267ff515e2bbe1674c847eea64a3c4eb151eeb94;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/cachebase.C b/cinelerra-5.1/cinelerra/cachebase.C new file mode 100644 index 00000000..267ff515 --- /dev/null +++ b/cinelerra-5.1/cinelerra/cachebase.C @@ -0,0 +1,243 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "asset.h" +#include "bcsignals.h" +#include "cachebase.h" +#include "edl.h" +#include "mutex.h" + +#include + + + + +CacheItemBase::CacheItemBase() + : ListItem() +{ + age = 0; + source_id = -1; + path = 0; +} + +CacheItemBase::~CacheItemBase() +{ + delete [] path; +} + + +int CacheItemBase::get_size() +{ + return 0; +} + +CacheBase::CacheBase() + : List() +{ + lock = new Mutex("CacheBase::lock"); + current_item = 0; + total_items = 0; +} + +CacheBase::~CacheBase() +{ + delete lock; +} + + + +int CacheBase::get_age() +{ + return EDL::next_id(); +} + + +// Called when done with the item returned by get_. +// Ignore if item was 0. +void CacheBase::unlock() +{ + lock->unlock(); +} + +void CacheBase::remove_all() +{ +//printf("CacheBase::remove_all: removed %d entries\n", total_items); + lock->lock("CacheBase::remove_all"); + while(last) delete last; + total_items = 0; + current_item = 0; + lock->unlock(); +} + + +void CacheBase::remove_asset(Asset *asset) +{ + CacheItemBase *current, *next; + lock->lock("CacheBase::remove_id"); + for( current=first; current; current=next ) { + next = current->next; + if( (current->path && !strcmp(current->path, asset->path)) || + current->source_id == asset->id) + del_item(current); + } + lock->unlock(); +//printf("CacheBase::remove_asset: removed %d entries for %s\n", total, asset->path); +} + + +void CacheBase::del_item(CacheItemBase *item) +{ + --total_items; + if( current_item == item ) + current_item = 0; + delete item; +} + +int CacheBase::delete_oldest() +{ + int result = 0; + lock->lock("CacheBase::delete_oldest"); + CacheItemBase *oldest, *current; + for( oldest=current=first; current; current=NEXT ) { + if( current->age < oldest->age ) + oldest = current; + } + if( oldest ) { + del_item(oldest); + result = 1; + } + lock->unlock(); + return result; +} + +int CacheBase::delete_item(CacheItemBase *item) +{ + lock->lock("CacheBase::delete_item"); +// Too much data to debug if audio. +// printf("CacheBase::delete_oldest: deleted position=%jd %d bytes\n", +// oldest_item->position, oldest_item->get_size()); + del_item(item); + lock->unlock(); + return 0; +} + + +int64_t CacheBase::get_memory_usage() +{ + int64_t result = 0; + lock->lock("CacheBase::get_memory_usage"); + for(CacheItemBase *current = first; current; current = NEXT) + { + result += current->get_size(); + } + lock->unlock(); + return result; +} + + +void CacheBase::put_item(CacheItemBase *item) +{ +// Get first position >= item + int64_t position = item->position; + if( !current_item && first ) { + int64_t lt_dist = first ? position - first->position : 0; + if( lt_dist < 0 ) lt_dist = 0; + int64_t rt_dist = last ? last->position - position : 0; + if( rt_dist < 0 ) rt_dist = 0; + current_item = lt_dist < rt_dist ? first : last; + } + while(current_item && current_item->position > position) + current_item = current_item->previous; + if( !current_item ) current_item = first; + while(current_item && position > current_item->position) + current_item = current_item->next; + insert_before(current_item, item); + ++total_items; +} + + +// Get first item from list with matching position or 0 if none found. +CacheItemBase* CacheBase::get_item(int64_t position) +{ +// Get first position >= item + int64_t dist = 0x7fffffffffffffff; + if( current_item ) { + dist = current_item->position - position; + if( dist < 0 ) dist = -dist; + } + if( first ) { + int64_t lt_dist = position - first->position; + int64_t rt_dist = last->position - position; + if( lt_dist < rt_dist ) { + if( lt_dist < dist ) current_item = first; + } + else { + if( rt_dist < dist ) current_item = last; + } + } + while(current_item && current_item->position < position) + current_item = current_item->next; + while(current_item && current_item->position >= position ) + current_item = current_item->previous; +// forward one item + current_item = current_item ? current_item->next : first; + CacheItemBase *result = current_item && current_item->position==position ? + current_item : 0; + return result; +} + + +void CacheBase::age_cache(int64_t max_items) +{ + lock->lock("CacheBase::age_cache"); + if( total_items > max_items ) { + CacheItemBase *items[total_items]; + int n = 0; + for( CacheItemBase *current=first; current; current=NEXT ) { + // insert items into heap + CacheItemBase *item = current; + int i, k; + int v = item->age; + for( i=n++; i>0 && vage; i=k ) + items[i] = items[k]; + items[i] = item; + } + //int starting_items = total_items; + while( n > 0 && total_items > max_items ) { + // delete lowest heap item + CacheItemBase *item = items[0]; + del_item(item); + int i, k; + for( i=0; (k=2*(i+1)) < n; i=k ) { + if( items[k]->age > items[k-1]->age ) --k; + items[i] = items[k]; + } + item = items[--n]; + int v = item->age; + for( ; i>0 && vage; i=k ) + items[i] = items[k]; + items[i] = item; + } + } + lock->unlock(); +//printf("age_cache total_items=%d+%d items\n", total_items,starting_items-total_items); +} +