From: Wim Taymans Date: Mon, 2 Dec 2002 22:39:56 +0000 (+0000) Subject: More cache updates X-Git-Tag: BRANCH-RELEASE-0_5_0-ROOT~38 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b3cef553cf765119ddd74adfa8b5c7cb5daade02;p=platform%2Fupstream%2Fgstreamer.git More cache updates Original commit message from CVS: More cache updates --- diff --git a/gst/caches/gstmemcache.c b/gst/caches/gstmemcache.c index 81e9acb448..0a599c3174 100644 --- a/gst/caches/gstmemcache.c +++ b/gst/caches/gstmemcache.c @@ -64,13 +64,13 @@ * then do a lookup in the Tree to get the required value. */ -typedef struct _GstMemCacheFormatIndex { +typedef struct { GstFormat format; gint offset; GTree *tree; } GstMemCacheFormatIndex; -typedef struct _GstMemCacheId { +typedef struct { gint id; GHashTable *format_index; } GstMemCacheId; @@ -196,11 +196,14 @@ mem_cache_compare (gconstpointer a, { GstMemCacheFormatIndex *index = user_data; gint64 val1, val2; + gint64 diff; val1 = GST_CACHE_ASSOC_VALUE (((GstCacheEntry *)a), index->offset); val2 = GST_CACHE_ASSOC_VALUE (((GstCacheEntry *)b), index->offset); - return val1 - val2; + diff = (val2 - val1); + + return (diff == 0 ? 0 : (diff > 0 ? 1 : -1)); } static void @@ -279,6 +282,54 @@ gst_mem_cache_add_entry (GstCache *cache, GstCacheEntry *entry) } } +typedef struct { + gint64 value; + GstMemCacheFormatIndex *index; + gboolean exact; + GstCacheEntry *lower; + gint64 low_diff; + GstCacheEntry *higher; + gint64 high_diff; +} GstMemCacheSearchData; + +static gint +mem_cache_search (gconstpointer a, + gconstpointer b) +{ + GstMemCacheSearchData *data = (GstMemCacheSearchData *) b; + GstMemCacheFormatIndex *index = data->index; + gint64 val1, val2; + gint64 diff; + + val1 = GST_CACHE_ASSOC_VALUE (((GstCacheEntry *)a), index->offset); + val2 = data->value; + + diff = (val1 - val2); + if (diff == 0) + return 0; + + /* exact matching, don't update low/high */ + if (data->exact) + return (diff > 0 ? 1 : -1); + + if (diff < 0) { + if (diff > data->low_diff) { + data->low_diff = diff; + data->lower = (GstCacheEntry *) a; + } + diff = -1; + } + else { + if (diff < data->high_diff) { + data->high_diff = diff; + data->higher = (GstCacheEntry *) a; + } + diff = 1; + } + + return diff; +} + static GstCacheEntry* gst_mem_cache_get_assoc_entry (GstCache *cache, gint id, GstCacheLookupMethod method, @@ -287,45 +338,44 @@ gst_mem_cache_get_assoc_entry (GstCache *cache, gint id, gpointer user_data) { GstMemCache *memcache = GST_MEM_CACHE (cache); - GList *walk = memcache->associations; - GList *next; - - /* FIXME use GTree here */ - while (walk) { - GstCacheEntry *entry = (GstCacheEntry *) walk->data; - - next = g_list_next (walk); - - if (entry->type == GST_CACHE_ENTRY_ASSOCIATION && entry->id == id) { - gint64 got; - - if (gst_cache_entry_assoc_map (entry, format, &got)) { - if (got == value && method == GST_CACHE_LOOKUP_EXACT) - return entry; - else { - gint64 got_next = G_MININT64; - GstCacheEntry *next_entry = NULL; - - if (next != NULL) { - next_entry = (GstCacheEntry *) next->data; - - gst_cache_entry_assoc_map (next_entry, format, &got_next); - } - - if ((got >= value) && (got_next <= value)) { - if (method == GST_CACHE_LOOKUP_BEFORE) - return next_entry; - else if (method == GST_CACHE_LOOKUP_AFTER) - return entry; - } - } - } + GstMemCacheId *id_index; + GstMemCacheFormatIndex *index; + GstCacheEntry *entry; + GstMemCacheSearchData data; + + id_index = g_hash_table_lookup (memcache->id_index, &id); + if (!id_index) + return NULL; + + index = g_hash_table_lookup (id_index->format_index, &format); + if (!index) + return NULL; + + data.value = value; + data.index = index; + data.exact = (method == GST_CACHE_LOOKUP_EXACT); + + /* setup data for low/high checks if we are not looking + * for an exact match */ + if (!data.exact) { + data.low_diff = G_MININT64; + data.lower = NULL; + data.high_diff = G_MAXINT64; + data.higher = NULL; + } + + entry = g_tree_search (index->tree, mem_cache_search, &data); + + /* get the low/high values if we're not exact */ + if (entry == NULL && !data.exact) { + if (method == GST_CACHE_LOOKUP_BEFORE) + entry = data.lower; + else if (method == GST_CACHE_LOOKUP_AFTER) { + entry = data.higher; } - - walk = next; } - return NULL; + return entry; } static gboolean diff --git a/gst/gstcache.c b/gst/gstcache.c index 038d429ad6..ae5aba96fc 100644 --- a/gst/gstcache.c +++ b/gst/gstcache.c @@ -246,6 +246,12 @@ gst_cache_set_resolver (GstCache *cache, cache->resolver_user_data = user_data; } +void +gst_cache_entry_free (GstCacheEntry *entry) +{ + g_free (entry); +} + /** * gst_cache_add_format: * @cache: the cache to add the entry to @@ -370,12 +376,14 @@ gst_cache_get_writer_id (GstCache *cache, GstObject *writer, gint *id) * @...: other format/value pairs or 0 to end the list * * Associate given format/value pairs with eachother. + * Be sure to pass gint64 values to this functions varargs, + * you might want to use a gint64 cast to be sure. * * Returns: a pointer to the newly added entry in the cache. */ GstCacheEntry* gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags, - GstFormat format, gint64 value, ...) + GstFormat format, gint64 value, ...) { va_list args; GstCacheAssociation *assoc; @@ -383,7 +391,7 @@ gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags, gulong size; gint nassocs = 0; GstFormat cur_format; - gint64 dummy; + volatile gint64 dummy; g_return_val_if_fail (GST_IS_CACHE (cache), NULL); g_return_val_if_fail (format != 0, NULL); @@ -433,6 +441,59 @@ gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags, return entry; } +static gint +gst_cache_compare_func (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + return a - b; +} + +GstCacheEntry* +gst_cache_get_assoc_entry (GstCache *cache, gint id, + GstCacheLookupMethod method, + GstFormat format, gint64 value) +{ + g_return_val_if_fail (GST_IS_CACHE (cache), NULL); + + return gst_cache_get_assoc_entry_full (cache, id, method, format, value, + gst_cache_compare_func, NULL); +} + +GstCacheEntry* +gst_cache_get_assoc_entry_full (GstCache *cache, gint id, + GstCacheLookupMethod method, + GstFormat format, gint64 value, + GCompareDataFunc func, + gpointer user_data) +{ + g_return_val_if_fail (GST_IS_CACHE (cache), NULL); + + if (CLASS(cache)->get_assoc_entry) + return CLASS (cache)->get_assoc_entry (cache, id, method, format, value, func, user_data); + + return NULL; +} + +gboolean +gst_cache_entry_assoc_map (GstCacheEntry *entry, + GstFormat format, gint64 *value) +{ + gint i; + + g_return_val_if_fail (entry != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + for (i = 0; i < GST_CACHE_NASSOCS (entry); i++) { + if (GST_CACHE_ASSOC_FORMAT (entry, i) == format) { + *value = GST_CACHE_ASSOC_VALUE (entry, i); + return TRUE; + } + } + return FALSE; +} + + static void gst_cache_factory_class_init (GstCacheFactoryClass *klass); static void gst_cache_factory_init (GstCacheFactory *factory); diff --git a/gst/gstcache.h b/gst/gstcache.h index d1237dcae1..a2acc1e265 100644 --- a/gst/gstcache.h +++ b/gst/gstcache.h @@ -53,6 +53,12 @@ typedef enum { GST_CACHE_ENTRY_FORMAT, } GstCacheEntryType; +typedef enum { + GST_CACHE_LOOKUP_EXACT, + GST_CACHE_LOOKUP_BEFORE, + GST_CACHE_LOOKUP_AFTER, +} GstCacheLookupMethod; + #define GST_CACHE_NASSOCS(entry) ((entry)->data.assoc.nassocs) #define GST_CACHE_ASSOC_FLAGS(entry) ((entry)->data.assoc.flags) #define GST_CACHE_ASSOC_FORMAT(entry,i) ((entry)->data.assoc.assocs[(i)].format) @@ -149,8 +155,11 @@ struct _GstCacheClass { /* abstract methods */ void (*add_entry) (GstCache *cache, GstCacheEntry *entry); - GstCacheEntry* (*get_entry) (GstCache *cache); - + GstCacheEntry* (*get_assoc_entry) (GstCache *cache, gint id, + GstCacheLookupMethod method, + GstFormat format, gint64 value, + GCompareDataFunc func, + gpointer user_data); /* signals */ void (*entry_added) (GstCache *cache, GstCacheEntry *entry); }; @@ -181,6 +190,19 @@ GstCacheEntry* gst_cache_add_object (GstCache *cache, gint id, gchar *key, GstCacheEntry* gst_cache_add_id (GstCache *cache, gint id, gchar *description); +GstCacheEntry* gst_cache_get_assoc_entry (GstCache *cache, gint id, + GstCacheLookupMethod method, + GstFormat format, gint64 value); +GstCacheEntry* gst_cache_get_assoc_entry_full (GstCache *cache, gint id, + GstCacheLookupMethod method, + GstFormat format, gint64 value, + GCompareDataFunc func, + gpointer user_data); + +/* working with cache entries */ +void gst_cache_entry_free (GstCacheEntry *entry); +gboolean gst_cache_entry_assoc_map (GstCacheEntry *entry, + GstFormat format, gint64 *value); /* * creating caches *