From f88ea12bacf381ad4f39ba2328c806e772c0dda8 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Tue, 1 Mar 2022 22:37:11 -0500 Subject: [PATCH] tagcache compress uniqbuf 2 16-bit indices occupy a single 32 bit slot a lot of space is wasted when file indices less than 65535 entries should be more than 1 byte apart so use the LSB as a flag when indices are > 65535 set flag to 0 and proceed as before explicitly mark uniqbuf as 32bit Change-Id: I54e06c152c369eb6c0322186fe2c1e9a1e6d940d --- apps/tagcache.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----- apps/tagcache.h | 2 +- apps/tagtree.c | 2 +- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/apps/tagcache.c b/apps/tagcache.c index 248e57237d..d09ddf486a 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -1209,7 +1209,7 @@ bool tagcache_check_clauses(struct tagcache_search *tcs, return check_clauses(tcs, &idx, clause, count); } -static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id) +static bool add_uniqbuf(struct tagcache_search *tcs, uint32_t id) { int i; @@ -1220,11 +1220,53 @@ static bool add_uniqbuf(struct tagcache_search *tcs, unsigned long id) return true; } - for (i = 0; i < tcs->unique_list_count; i++) + if (id <= UINT16_MAX) { - /* Return false if entry is found. */ - if (tcs->unique_list[i] == id) - return false; + /* place two 16-bit entries in a single 32-bit slot */ + uint32_t idtmp; + union uentry{ + uint16_t u16[2]; + uint32_t u32; + } *entry; + id |= 1; /*odd - flag 16-bit entry */ + for (i = 0; i < tcs->unique_list_count; i++) + { + entry = (union uentry *) &tcs->unique_list[i]; + if ((entry->u32 & 1) == 0) /* contains a 32-bit entry */ + continue; + + /* Return false if entry is found. */ + if (entry->u16[0] == id || entry->u16[1] == id) + { + logf("%d Exists (16) @ %d", id, i); + return false; + } + + if (entry->u16[1] == 0 && (entry->u16[0] & 1) == 1) + { + entry->u16[1] = id & UINT16_MAX; + return true; /*no more 16bit entries add to empty 16bit slot */ + } + + } + /* Not Found and no empty slot add a new entry */ + entry = (union uentry *) &idtmp; + entry->u16[1] = 0; + entry->u16[0] = id & UINT16_MAX; + id = idtmp; + } + else + { + id &= ~1; /* even - flag 32-bit entry */ + for (i = 0; i < tcs->unique_list_count; i++) + { + /* Return false if entry is found. */ + if (tcs->unique_list[i] == id) + { + logf("%d Exists (32)@ %d", id, i); + return false; + } + } } if (tcs->unique_list_count < tcs->unique_list_capacity) @@ -1470,9 +1512,10 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) void tagcache_search_set_uniqbuf(struct tagcache_search *tcs, void *buffer, long length) { - tcs->unique_list = (unsigned long *)buffer; + tcs->unique_list = (uint32_t *)buffer; tcs->unique_list_capacity = length / sizeof(*tcs->unique_list); tcs->unique_list_count = 0; + memset(tcs->unique_list, 0, tcs->unique_list_capacity); } bool tagcache_search_add_filter(struct tagcache_search *tcs, @@ -1702,6 +1745,11 @@ bool tagcache_get_next(struct tagcache_search *tcs) return true; } +#ifdef LOGF_ENABLE + if (tcs->unique_list_count > 0) + logf(" uniqbuf: %d used / %d avail", tcs->unique_list_count, tcs->unique_list_capacity); +#endif + return false; } diff --git a/apps/tagcache.h b/apps/tagcache.h index 52a9283e35..b7c4aadbb1 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -188,7 +188,7 @@ struct tagcache_search { int entry_count; bool valid; bool initialized; - unsigned long *unique_list; + uint32_t *unique_list; int unique_list_capacity; int unique_list_count; diff --git a/apps/tagtree.c b/apps/tagtree.c index 9684d5424c..48ef1e28ce 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c @@ -111,7 +111,7 @@ enum variables { /* Capacity 10 000 entries (for example 10k different artists) */ #define UNIQBUF_SIZE (64*1024) -static long uniqbuf[UNIQBUF_SIZE / sizeof(long)]; +static uint32_t uniqbuf[UNIQBUF_SIZE / sizeof(uint32_t)]; #define MAX_TAGS 5 #define MAX_MENU_ID_SIZE 32