mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-13 01:35:30 +00:00
More cache updates
Original commit message from CVS: More cache updates
This commit is contained in:
parent
1ce6deb624
commit
b3cef553cf
3 changed files with 173 additions and 40 deletions
|
@ -64,13 +64,13 @@
|
||||||
* then do a lookup in the Tree to get the required value.
|
* then do a lookup in the Tree to get the required value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _GstMemCacheFormatIndex {
|
typedef struct {
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint offset;
|
gint offset;
|
||||||
GTree *tree;
|
GTree *tree;
|
||||||
} GstMemCacheFormatIndex;
|
} GstMemCacheFormatIndex;
|
||||||
|
|
||||||
typedef struct _GstMemCacheId {
|
typedef struct {
|
||||||
gint id;
|
gint id;
|
||||||
GHashTable *format_index;
|
GHashTable *format_index;
|
||||||
} GstMemCacheId;
|
} GstMemCacheId;
|
||||||
|
@ -196,11 +196,14 @@ mem_cache_compare (gconstpointer a,
|
||||||
{
|
{
|
||||||
GstMemCacheFormatIndex *index = user_data;
|
GstMemCacheFormatIndex *index = user_data;
|
||||||
gint64 val1, val2;
|
gint64 val1, val2;
|
||||||
|
gint64 diff;
|
||||||
|
|
||||||
val1 = GST_CACHE_ASSOC_VALUE (((GstCacheEntry *)a), index->offset);
|
val1 = GST_CACHE_ASSOC_VALUE (((GstCacheEntry *)a), index->offset);
|
||||||
val2 = GST_CACHE_ASSOC_VALUE (((GstCacheEntry *)b), 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
|
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*
|
static GstCacheEntry*
|
||||||
gst_mem_cache_get_assoc_entry (GstCache *cache, gint id,
|
gst_mem_cache_get_assoc_entry (GstCache *cache, gint id,
|
||||||
GstCacheLookupMethod method,
|
GstCacheLookupMethod method,
|
||||||
|
@ -287,45 +338,44 @@ gst_mem_cache_get_assoc_entry (GstCache *cache, gint id,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GstMemCache *memcache = GST_MEM_CACHE (cache);
|
GstMemCache *memcache = GST_MEM_CACHE (cache);
|
||||||
GList *walk = memcache->associations;
|
GstMemCacheId *id_index;
|
||||||
GList *next;
|
GstMemCacheFormatIndex *index;
|
||||||
|
GstCacheEntry *entry;
|
||||||
|
GstMemCacheSearchData data;
|
||||||
|
|
||||||
/* FIXME use GTree here */
|
id_index = g_hash_table_lookup (memcache->id_index, &id);
|
||||||
while (walk) {
|
if (!id_index)
|
||||||
GstCacheEntry *entry = (GstCacheEntry *) walk->data;
|
return NULL;
|
||||||
|
|
||||||
next = g_list_next (walk);
|
index = g_hash_table_lookup (id_index->format_index, &format);
|
||||||
|
if (!index)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (entry->type == GST_CACHE_ENTRY_ASSOCIATION && entry->id == id) {
|
data.value = value;
|
||||||
gint64 got;
|
data.index = index;
|
||||||
|
data.exact = (method == GST_CACHE_LOOKUP_EXACT);
|
||||||
|
|
||||||
if (gst_cache_entry_assoc_map (entry, format, &got)) {
|
/* setup data for low/high checks if we are not looking
|
||||||
if (got == value && method == GST_CACHE_LOOKUP_EXACT)
|
* for an exact match */
|
||||||
return entry;
|
if (!data.exact) {
|
||||||
else {
|
data.low_diff = G_MININT64;
|
||||||
gint64 got_next = G_MININT64;
|
data.lower = NULL;
|
||||||
GstCacheEntry *next_entry = NULL;
|
data.high_diff = G_MAXINT64;
|
||||||
|
data.higher = 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
walk = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -246,6 +246,12 @@ gst_cache_set_resolver (GstCache *cache,
|
||||||
cache->resolver_user_data = user_data;
|
cache->resolver_user_data = user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_cache_entry_free (GstCacheEntry *entry)
|
||||||
|
{
|
||||||
|
g_free (entry);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_cache_add_format:
|
* gst_cache_add_format:
|
||||||
* @cache: the cache to add the entry to
|
* @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
|
* @...: other format/value pairs or 0 to end the list
|
||||||
*
|
*
|
||||||
* Associate given format/value pairs with eachother.
|
* 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.
|
* Returns: a pointer to the newly added entry in the cache.
|
||||||
*/
|
*/
|
||||||
GstCacheEntry*
|
GstCacheEntry*
|
||||||
gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags,
|
gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags,
|
||||||
GstFormat format, gint64 value, ...)
|
GstFormat format, gint64 value, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
GstCacheAssociation *assoc;
|
GstCacheAssociation *assoc;
|
||||||
|
@ -383,7 +391,7 @@ gst_cache_add_association (GstCache *cache, gint id, GstAssocFlags flags,
|
||||||
gulong size;
|
gulong size;
|
||||||
gint nassocs = 0;
|
gint nassocs = 0;
|
||||||
GstFormat cur_format;
|
GstFormat cur_format;
|
||||||
gint64 dummy;
|
volatile gint64 dummy;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_CACHE (cache), NULL);
|
g_return_val_if_fail (GST_IS_CACHE (cache), NULL);
|
||||||
g_return_val_if_fail (format != 0, 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;
|
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_class_init (GstCacheFactoryClass *klass);
|
||||||
static void gst_cache_factory_init (GstCacheFactory *factory);
|
static void gst_cache_factory_init (GstCacheFactory *factory);
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,12 @@ typedef enum {
|
||||||
GST_CACHE_ENTRY_FORMAT,
|
GST_CACHE_ENTRY_FORMAT,
|
||||||
} GstCacheEntryType;
|
} 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_NASSOCS(entry) ((entry)->data.assoc.nassocs)
|
||||||
#define GST_CACHE_ASSOC_FLAGS(entry) ((entry)->data.assoc.flags)
|
#define GST_CACHE_ASSOC_FLAGS(entry) ((entry)->data.assoc.flags)
|
||||||
#define GST_CACHE_ASSOC_FORMAT(entry,i) ((entry)->data.assoc.assocs[(i)].format)
|
#define GST_CACHE_ASSOC_FORMAT(entry,i) ((entry)->data.assoc.assocs[(i)].format)
|
||||||
|
@ -149,8 +155,11 @@ struct _GstCacheClass {
|
||||||
/* abstract methods */
|
/* abstract methods */
|
||||||
void (*add_entry) (GstCache *cache, GstCacheEntry *entry);
|
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 */
|
/* signals */
|
||||||
void (*entry_added) (GstCache *cache, GstCacheEntry *entry);
|
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,
|
GstCacheEntry* gst_cache_add_id (GstCache *cache, gint id,
|
||||||
gchar *description);
|
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
|
* creating caches
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue