summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/hash.h20
-rw-r--r--source/fitz/colorspace.c19
-rw-r--r--source/fitz/hash.c88
-rw-r--r--source/fitz/store.c9
-rw-r--r--source/pdf/pdf-resources.c21
5 files changed, 45 insertions, 112 deletions
diff --git a/include/mupdf/fitz/hash.h b/include/mupdf/fitz/hash.h
index 4b1d7a05..89a56bc3 100644
--- a/include/mupdf/fitz/hash.h
+++ b/include/mupdf/fitz/hash.h
@@ -7,23 +7,25 @@
/*
* Generic hash-table with fixed-length keys.
+ *
+ * The keys and values are NOT reference counted by the hash table.
+ * Callers are responsible for taking care the reference counts are correct.
+ * Inserting a duplicate entry will NOT overwrite the old value, and will
+ * return the old value.
+ *
+ * The drop_val callback function is only used to release values when the hash table
+ * is destroyed.
*/
typedef struct fz_hash_table_s fz_hash_table;
+typedef void (*fz_hash_table_drop_fn)(fz_context *ctx, void *val);
-fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock);
-void fz_empty_hash(fz_context *ctx, fz_hash_table *table);
-void fz_drop_hash(fz_context *ctx, fz_hash_table *table);
+fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock, fz_hash_table_drop_fn drop_val);
+void fz_drop_hash_table(fz_context *ctx, fz_hash_table *table);
void *fz_hash_find(fz_context *ctx, fz_hash_table *table, const void *key);
void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val);
-void *fz_hash_insert_with_pos(fz_context *ctx, fz_hash_table *table, const void *key, void *val, unsigned *pos);
void fz_hash_remove(fz_context *ctx, fz_hash_table *table, const void *key);
-void fz_hash_remove_fast(fz_context *ctx, fz_hash_table *table, const void *key, unsigned pos);
-
-int fz_hash_len(fz_context *ctx, fz_hash_table *table);
-void *fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx);
-void *fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx);
void fz_print_hash(fz_context *ctx, fz_output *out, fz_hash_table *table);
void fz_print_hash_details(fz_context *ctx, fz_output *out, fz_hash_table *table, void (*details)(fz_context*, fz_output*, void*), int compact);
diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c
index 21517db2..c7385a60 100644
--- a/source/fitz/colorspace.c
+++ b/source/fitz/colorspace.c
@@ -1641,7 +1641,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
fz_color_converter cc;
fz_lookup_color_converter(ctx, &cc, ds, ss);
- lookup = fz_new_hash_table(ctx, 509, srcn, -1);
+ lookup = fz_new_hash_table(ctx, 509, srcn, -1, NULL);
while (h--)
{
@@ -1692,7 +1692,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
s += s_line_inc;
}
- fz_drop_hash(ctx, lookup);
+ fz_drop_hash_table(ctx, lookup);
}
}
@@ -2133,7 +2133,7 @@ void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_
fz_try(ctx)
{
fz_lookup_color_converter(ctx, &cached->base, ds, ss);
- cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1);
+ cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1, fz_free);
cc->convert = fz_cached_color_convert;
cc->ds = ds;
cc->ss = ss;
@@ -2141,7 +2141,7 @@ void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_
}
fz_catch(ctx)
{
- fz_drop_hash(ctx, cached->hash);
+ fz_drop_hash_table(ctx, cached->hash);
fz_rethrow(ctx);
}
}
@@ -2149,22 +2149,13 @@ void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_
void fz_fin_cached_color_converter(fz_context *ctx, fz_color_converter *cc_)
{
fz_cached_color_converter *cc;
- int i, n;
-
if (cc_ == NULL)
return;
cc = cc_->opaque;
if (cc == NULL)
return;
cc_->opaque = NULL;
-
- n = fz_hash_len(ctx, cc->hash);
- for (i = 0; i < n; i++)
- {
- void *v = fz_hash_get_val(ctx, cc->hash, i);
- fz_free(ctx, v);
- }
- fz_drop_hash(ctx, cc->hash);
+ fz_drop_hash_table(ctx, cc->hash);
fz_free(ctx, cc);
}
diff --git a/source/fitz/hash.c b/source/fitz/hash.c
index e16aefd1..7e4f49f1 100644
--- a/source/fitz/hash.c
+++ b/source/fitz/hash.c
@@ -23,6 +23,7 @@ struct fz_hash_table_s
int size;
int load;
int lock; /* -1 or the lock used to protect this hash table */
+ fz_hash_table_drop_fn drop_val;
fz_hash_entry *ents;
};
@@ -43,7 +44,7 @@ static unsigned hash(const unsigned char *s, int len)
}
fz_hash_table *
-fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock)
+fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock, fz_hash_table_drop_fn drop_val)
{
fz_hash_table *table;
@@ -54,6 +55,7 @@ fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock)
table->size = initialsize;
table->load = 0;
table->lock = lock;
+ table->drop_val = drop_val;
fz_try(ctx)
{
table->ents = fz_malloc_array(ctx, table->size, sizeof(fz_hash_entry));
@@ -69,42 +71,28 @@ fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock)
}
void
-fz_empty_hash(fz_context *ctx, fz_hash_table *table)
-{
- table->load = 0;
- memset(table->ents, 0, sizeof(fz_hash_entry) * table->size);
-}
-
-int
-fz_hash_len(fz_context *ctx, fz_hash_table *table)
-{
- return table->size;
-}
-
-void *
-fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx)
-{
- return table->ents[idx].key;
-}
-
-void *
-fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx)
-{
- return table->ents[idx].val;
-}
-
-void
-fz_drop_hash(fz_context *ctx, fz_hash_table *table)
+fz_drop_hash_table(fz_context *ctx, fz_hash_table *table)
{
if (!table)
return;
+ if (table->drop_val)
+ {
+ int i, n = table->size;
+ for (i = 0; i < n; ++i)
+ {
+ void *v = table->ents[i].val;
+ if (v)
+ table->drop_val(ctx, v);
+ }
+ }
+
fz_free(ctx, table->ents);
fz_free(ctx, table);
}
static void *
-do_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val, unsigned *pos_ptr)
+do_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val)
{
fz_hash_entry *ents;
unsigned size;
@@ -124,19 +112,13 @@ do_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val
memcpy(ents[pos].key, key, table->keylen);
ents[pos].val = val;
table->load ++;
- if (pos_ptr)
- *pos_ptr = pos;
return NULL;
}
if (memcmp(key, ents[pos].key, table->keylen) == 0)
{
- /* This is legal, but should happen rarely in the non
- * pos_ptr case. */
- if (pos_ptr)
- *pos_ptr = pos;
- else
- fz_warn(ctx, "assert: overwrite hash slot");
+ /* This is legal, but should happen rarely. */
+ fz_warn(ctx, "assert: overwrite hash slot");
return ents[pos].val;
}
@@ -190,7 +172,7 @@ fz_resize_hash(fz_context *ctx, fz_hash_table *table, int newsize)
{
if (oldents[i].val)
{
- do_hash_insert(ctx, table, oldents[i].key, oldents[i].val, NULL);
+ do_hash_insert(ctx, table, oldents[i].key, oldents[i].val);
}
}
@@ -227,22 +209,8 @@ void *
fz_hash_insert(fz_context *ctx, fz_hash_table *table, const void *key, void *val)
{
if (table->load > table->size * 8 / 10)
- {
fz_resize_hash(ctx, table, table->size * 2);
- }
-
- return do_hash_insert(ctx, table, key, val, NULL);
-}
-
-void *
-fz_hash_insert_with_pos(fz_context *ctx, fz_hash_table *table, const void *key, void *val, unsigned *pos)
-{
- if (table->load > table->size * 8 / 10)
- {
- fz_resize_hash(ctx, table, table->size * 2);
- }
-
- return do_hash_insert(ctx, table, key, val, pos);
+ return do_hash_insert(ctx, table, key, val);
}
static void
@@ -312,22 +280,6 @@ fz_hash_remove(fz_context *ctx, fz_hash_table *table, const void *key)
}
void
-fz_hash_remove_fast(fz_context *ctx, fz_hash_table *table, const void *key, unsigned pos)
-{
- fz_hash_entry *ents = table->ents;
-
- if (ents[pos].val == NULL || memcmp(key, ents[pos].key, table->keylen) != 0)
- {
- /* The value isn't there, or the key didn't match! The table
- * must have been rebuilt (or the contents moved) in the
- * meantime. Do the removal the slow way. */
- fz_hash_remove(ctx, table, key);
- }
- else
- do_removal(ctx, table, key, pos);
-}
-
-void
fz_print_hash(fz_context *ctx, fz_output *out, fz_hash_table *table)
{
fz_print_hash_details(ctx, out, table, NULL, 0);
diff --git a/source/fitz/store.c b/source/fitz/store.c
index c9a07428..b3996686 100644
--- a/source/fitz/store.c
+++ b/source/fitz/store.c
@@ -42,7 +42,7 @@ fz_new_store_context(fz_context *ctx, size_t max)
store = fz_malloc_struct(ctx, fz_store);
fz_try(ctx)
{
- store->hash = fz_new_hash_table(ctx, 4096, sizeof(fz_store_hash), FZ_LOCK_ALLOC);
+ store->hash = fz_new_hash_table(ctx, 4096, sizeof(fz_store_hash), FZ_LOCK_ALLOC, NULL);
}
fz_catch(ctx)
{
@@ -396,7 +396,6 @@ fz_store_item(fz_context *ctx, void *key, void *val_, size_t itemsize, fz_store_
fz_store *store = ctx->store;
fz_store_hash hash = { NULL };
int use_hash = 0;
- unsigned pos;
if (!store)
return NULL;
@@ -444,7 +443,7 @@ fz_store_item(fz_context *ctx, void *key, void *val_, size_t itemsize, fz_store_
fz_try(ctx)
{
/* May drop and retake the lock */
- existing = fz_hash_insert_with_pos(ctx, store->hash, &hash, item, &pos);
+ existing = fz_hash_insert(ctx, store->hash, &hash, item);
}
fz_catch(ctx)
{
@@ -468,9 +467,11 @@ fz_store_item(fz_context *ctx, void *key, void *val_, size_t itemsize, fz_store_
return existing->val;
}
}
+
/* Now bump the ref */
if (val->refs > 0)
val->refs++;
+
/* If we haven't got an infinite store, check for space within it */
if (store->max != FZ_STORE_UNLIMITED)
{
@@ -665,7 +666,7 @@ fz_drop_store_context(fz_context *ctx)
if (fz_drop_imp(ctx, ctx->store, &ctx->store->refs))
{
fz_empty_store(ctx);
- fz_drop_hash(ctx, ctx->store->hash);
+ fz_drop_hash_table(ctx, ctx->store->hash);
fz_free(ctx, ctx->store);
ctx->store = NULL;
}
diff --git a/source/pdf/pdf-resources.c b/source/pdf/pdf-resources.c
index ad195393..002906f8 100644
--- a/source/pdf/pdf-resources.c
+++ b/source/pdf/pdf-resources.c
@@ -76,7 +76,7 @@ pdf_find_image_resource(fz_context *ctx, pdf_document *doc, fz_image *item, unsi
if (!doc->resources.images)
{
- doc->resources.images = fz_new_hash_table(ctx, 4096, 16, -1);
+ doc->resources.images = fz_new_hash_table(ctx, 4096, 16, -1, (fz_hash_table_drop_fn)pdf_drop_obj);
pdf_preload_image_resources(ctx, doc);
}
@@ -110,7 +110,7 @@ pdf_find_font_resource(fz_context *ctx, pdf_document *doc, fz_buffer *item, unsi
pdf_obj *res;
if (!doc->resources.fonts)
- doc->resources.fonts = fz_new_hash_table(ctx, 4096, 16, -1);
+ doc->resources.fonts = fz_new_hash_table(ctx, 4096, 16, -1, (fz_hash_table_drop_fn)pdf_drop_obj);
/* Create md5 and see if we have the item in our table */
fz_md5_buffer(ctx, item, digest);
@@ -131,25 +131,12 @@ pdf_insert_font_resource(fz_context *ctx, pdf_document *doc, unsigned char diges
return res;
}
-static void
-res_table_free(fz_context *ctx, fz_hash_table *hash)
-{
- int i, n;
- if (hash)
- {
- n = fz_hash_len(ctx, hash);
- for (i = 0; i < n; i++)
- pdf_drop_obj(ctx, fz_hash_get_val(ctx, hash, i));
- fz_drop_hash(ctx, hash);
- }
-}
-
void
pdf_drop_resource_tables(fz_context *ctx, pdf_document *doc)
{
if (doc)
{
- res_table_free(ctx, doc->resources.fonts);
- res_table_free(ctx, doc->resources.images);
+ fz_drop_hash_table(ctx, doc->resources.fonts);
+ fz_drop_hash_table(ctx, doc->resources.images);
}
}