diff options
-rw-r--r-- | include/mupdf/fitz/hash.h | 20 | ||||
-rw-r--r-- | source/fitz/colorspace.c | 19 | ||||
-rw-r--r-- | source/fitz/hash.c | 88 | ||||
-rw-r--r-- | source/fitz/store.c | 9 | ||||
-rw-r--r-- | source/pdf/pdf-resources.c | 21 |
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); } } |