Mercurial > mplayer.hg
comparison libass/ass_cache.c @ 30200:48d020c5ceca
Update internal libass copy to commit 8db4a5
author | greg |
---|---|
date | Fri, 08 Jan 2010 18:35:44 +0000 |
parents | 0f1b5b68af32 |
children | e64df5862cea |
comparison
equal
deleted
inserted
replaced
30199:f9984b2fc1b2 | 30200:48d020c5ceca |
---|---|
1 // -*- c-basic-offset: 8; indent-tabs-mode: t -*- | |
2 // vim:ts=8:sw=8:noet:ai: | |
3 /* | 1 /* |
4 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2 * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> |
5 * | 3 * |
6 * This file is part of libass. | 4 * This file is part of libass. |
7 * | 5 * |
27 #include FT_FREETYPE_H | 25 #include FT_FREETYPE_H |
28 #include FT_GLYPH_H | 26 #include FT_GLYPH_H |
29 | 27 |
30 #include <assert.h> | 28 #include <assert.h> |
31 | 29 |
32 #include "mputils.h" | 30 #include "ass_utils.h" |
33 #include "ass.h" | 31 #include "ass.h" |
34 #include "ass_fontconfig.h" | 32 #include "ass_fontconfig.h" |
35 #include "ass_font.h" | 33 #include "ass_font.h" |
36 #include "ass_bitmap.h" | 34 #include "ass_bitmap.h" |
37 #include "ass_cache.h" | 35 #include "ass_cache.h" |
38 | 36 |
39 | 37 static unsigned hashmap_hash(void *buf, size_t len) |
40 typedef struct hashmap_item_s { | 38 { |
41 void* key; | 39 return fnv_32a_buf(buf, len, FNV1_32A_INIT); |
42 void* value; | 40 } |
43 struct hashmap_item_s* next; | 41 |
44 } hashmap_item_t; | 42 static int hashmap_key_compare(void *a, void *b, size_t size) |
45 typedef hashmap_item_t* hashmap_item_p; | 43 { |
46 | 44 return memcmp(a, b, size) == 0; |
47 struct hashmap_s { | 45 } |
48 int nbuckets; | 46 |
49 size_t key_size, value_size; | 47 static void hashmap_item_dtor(void *key, size_t key_size, void *value, |
50 hashmap_item_p* root; | 48 size_t value_size) |
51 hashmap_item_dtor_t item_dtor; // a destructor for hashmap key/value pairs | 49 { |
52 hashmap_key_compare_t key_compare; | 50 free(key); |
53 hashmap_hash_t hash; | 51 free(value); |
54 // stats | 52 } |
55 int hit_count; | 53 |
56 int miss_count; | 54 Hashmap *hashmap_init(ASS_Library *library, size_t key_size, |
57 int count; | 55 size_t value_size, int nbuckets, |
58 }; | 56 HashmapItemDtor item_dtor, |
59 | 57 HashmapKeyCompare key_compare, |
60 #define FNV1_32A_INIT (unsigned)0x811c9dc5 | 58 HashmapHash hash) |
61 | 59 { |
62 static inline unsigned fnv_32a_buf(void* buf, size_t len, unsigned hval) | 60 Hashmap *map = calloc(1, sizeof(Hashmap)); |
63 { | 61 map->library = library; |
64 unsigned char *bp = buf; | 62 map->nbuckets = nbuckets; |
65 unsigned char *be = bp + len; | 63 map->key_size = key_size; |
66 while (bp < be) { | 64 map->value_size = value_size; |
67 hval ^= (unsigned)*bp++; | 65 map->root = calloc(nbuckets, sizeof(hashmap_item_p)); |
68 hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); | 66 map->item_dtor = item_dtor ? item_dtor : hashmap_item_dtor; |
69 } | 67 map->key_compare = key_compare ? key_compare : hashmap_key_compare; |
70 return hval; | 68 map->hash = hash ? hash : hashmap_hash; |
71 } | 69 return map; |
72 static inline unsigned fnv_32a_str(char* str, unsigned hval) | 70 } |
73 { | 71 |
74 unsigned char* s = (unsigned char*)str; | 72 void hashmap_done(Hashmap *map) |
75 while (*s) { | 73 { |
76 hval ^= (unsigned)*s++; | 74 int i; |
77 hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); | 75 // print stats |
78 } | 76 if (map->count > 0 || map->hit_count + map->miss_count > 0) |
79 return hval; | 77 ass_msg(map->library, MSGL_V, |
80 } | 78 "cache statistics: \n total accesses: %d\n hits: %d\n " |
81 | 79 "misses: %d\n object count: %d", |
82 static unsigned hashmap_hash(void* buf, size_t len) | 80 map->hit_count + map->miss_count, map->hit_count, |
83 { | 81 map->miss_count, map->count); |
84 return fnv_32a_buf(buf, len, FNV1_32A_INIT); | 82 |
85 } | 83 for (i = 0; i < map->nbuckets; ++i) { |
86 | 84 HashmapItem *item = map->root[i]; |
87 static int hashmap_key_compare(void* a, void* b, size_t size) | 85 while (item) { |
88 { | 86 HashmapItem *next = item->next; |
89 return memcmp(a, b, size) == 0; | 87 map->item_dtor(item->key, map->key_size, item->value, |
90 } | 88 map->value_size); |
91 | 89 free(item); |
92 static void hashmap_item_dtor(void* key, size_t key_size, void* value, size_t value_size) | 90 item = next; |
93 { | 91 } |
94 free(key); | 92 } |
95 free(value); | 93 free(map->root); |
96 } | 94 free(map); |
97 | |
98 hashmap_t* hashmap_init(size_t key_size, size_t value_size, int nbuckets, | |
99 hashmap_item_dtor_t item_dtor, hashmap_key_compare_t key_compare, | |
100 hashmap_hash_t hash) | |
101 { | |
102 hashmap_t* map = calloc(1, sizeof(hashmap_t)); | |
103 map->nbuckets = nbuckets; | |
104 map->key_size = key_size; | |
105 map->value_size = value_size; | |
106 map->root = calloc(nbuckets, sizeof(hashmap_item_p)); | |
107 map->item_dtor = item_dtor ? item_dtor : hashmap_item_dtor; | |
108 map->key_compare = key_compare ? key_compare : hashmap_key_compare; | |
109 map->hash = hash ? hash : hashmap_hash; | |
110 return map; | |
111 } | |
112 | |
113 void hashmap_done(hashmap_t* map) | |
114 { | |
115 int i; | |
116 // print stats | |
117 if (map->count > 0 || map->hit_count + map->miss_count > 0) | |
118 mp_msg(MSGT_ASS, MSGL_V, "cache statistics: \n total accesses: %d\n hits: %d\n misses: %d\n object count: %d\n", | |
119 map->hit_count + map->miss_count, map->hit_count, map->miss_count, map->count); | |
120 | |
121 for (i = 0; i < map->nbuckets; ++i) { | |
122 hashmap_item_t* item = map->root[i]; | |
123 while (item) { | |
124 hashmap_item_t* next = item->next; | |
125 map->item_dtor(item->key, map->key_size, item->value, map->value_size); | |
126 free(item); | |
127 item = next; | |
128 } | |
129 } | |
130 free(map->root); | |
131 free(map); | |
132 } | 95 } |
133 | 96 |
134 // does nothing if key already exists | 97 // does nothing if key already exists |
135 void* hashmap_insert(hashmap_t* map, void* key, void* value) | 98 void *hashmap_insert(Hashmap *map, void *key, void *value) |
136 { | 99 { |
137 unsigned hash = map->hash(key, map->key_size); | 100 unsigned hash = map->hash(key, map->key_size); |
138 hashmap_item_t** next = map->root + (hash % map->nbuckets); | 101 HashmapItem **next = map->root + (hash % map->nbuckets); |
139 while (*next) { | 102 while (*next) { |
140 if (map->key_compare(key, (*next)->key, map->key_size)) | 103 if (map->key_compare(key, (*next)->key, map->key_size)) |
141 return (*next)->value; | 104 return (*next)->value; |
142 next = &((*next)->next); | 105 next = &((*next)->next); |
143 assert(next); | 106 assert(next); |
144 } | 107 } |
145 (*next) = malloc(sizeof(hashmap_item_t)); | 108 (*next) = malloc(sizeof(HashmapItem)); |
146 (*next)->key = malloc(map->key_size); | 109 (*next)->key = malloc(map->key_size); |
147 (*next)->value = malloc(map->value_size); | 110 (*next)->value = malloc(map->value_size); |
148 memcpy((*next)->key, key, map->key_size); | 111 memcpy((*next)->key, key, map->key_size); |
149 memcpy((*next)->value, value, map->value_size); | 112 memcpy((*next)->value, value, map->value_size); |
150 (*next)->next = 0; | 113 (*next)->next = 0; |
151 | 114 |
152 map->count ++; | 115 map->count++; |
153 return (*next)->value; | 116 return (*next)->value; |
154 } | 117 } |
155 | 118 |
156 void* hashmap_find(hashmap_t* map, void* key) | 119 void *hashmap_find(Hashmap *map, void *key) |
157 { | 120 { |
158 unsigned hash = map->hash(key, map->key_size); | 121 unsigned hash = map->hash(key, map->key_size); |
159 hashmap_item_t* item = map->root[hash % map->nbuckets]; | 122 HashmapItem *item = map->root[hash % map->nbuckets]; |
160 while (item) { | 123 while (item) { |
161 if (map->key_compare(key, item->key, map->key_size)) { | 124 if (map->key_compare(key, item->key, map->key_size)) { |
162 map->hit_count++; | 125 map->hit_count++; |
163 return item->value; | 126 return item->value; |
164 } | 127 } |
165 item = item->next; | 128 item = item->next; |
166 } | 129 } |
167 map->miss_count++; | 130 map->miss_count++; |
168 return 0; | 131 return 0; |
169 } | 132 } |
170 | 133 |
171 //--------------------------------- | 134 //--------------------------------- |
172 // font cache | 135 // font cache |
173 | 136 |
174 hashmap_t* font_cache; | 137 static unsigned font_desc_hash(void *buf, size_t len) |
175 | 138 { |
176 static unsigned font_desc_hash(void* buf, size_t len) | 139 ASS_FontDesc *desc = buf; |
177 { | 140 unsigned hval; |
178 ass_font_desc_t* desc = buf; | 141 hval = fnv_32a_str(desc->family, FNV1_32A_INIT); |
179 unsigned hval; | 142 hval = fnv_32a_buf(&desc->bold, sizeof(desc->bold), hval); |
180 hval = fnv_32a_str(desc->family, FNV1_32A_INIT); | 143 hval = fnv_32a_buf(&desc->italic, sizeof(desc->italic), hval); |
181 hval = fnv_32a_buf(&desc->bold, sizeof(desc->bold), hval); | 144 return hval; |
182 hval = fnv_32a_buf(&desc->italic, sizeof(desc->italic), hval); | 145 } |
183 return hval; | 146 |
184 } | 147 static int font_compare(void *key1, void *key2, size_t key_size) |
185 | 148 { |
186 static int font_compare(void* key1, void* key2, size_t key_size) { | 149 ASS_FontDesc *a = key1; |
187 ass_font_desc_t* a = key1; | 150 ASS_FontDesc *b = key2; |
188 ass_font_desc_t* b = key2; | 151 if (strcmp(a->family, b->family) != 0) |
189 if (strcmp(a->family, b->family) != 0) | 152 return 0; |
190 return 0; | 153 if (a->bold != b->bold) |
191 if (a->bold != b->bold) | 154 return 0; |
192 return 0; | 155 if (a->italic != b->italic) |
193 if (a->italic != b->italic) | 156 return 0; |
194 return 0; | 157 if (a->treat_family_as_pattern != b->treat_family_as_pattern) |
195 if (a->treat_family_as_pattern != b->treat_family_as_pattern) | 158 return 0; |
196 return 0; | 159 return 1; |
197 return 1; | 160 } |
198 } | 161 |
199 | 162 static void font_hash_dtor(void *key, size_t key_size, void *value, |
200 static void font_hash_dtor(void* key, size_t key_size, void* value, size_t value_size) | 163 size_t value_size) |
201 { | 164 { |
202 ass_font_free(value); | 165 ass_font_free(value); |
203 free(key); | 166 free(key); |
204 } | 167 } |
205 | 168 |
206 ass_font_t* ass_font_cache_find(ass_font_desc_t* desc) | 169 ASS_Font *ass_font_cache_find(Hashmap *font_cache, |
207 { | 170 ASS_FontDesc *desc) |
208 return hashmap_find(font_cache, desc); | 171 { |
172 return hashmap_find(font_cache, desc); | |
209 } | 173 } |
210 | 174 |
211 /** | 175 /** |
212 * \brief Add a face struct to cache. | 176 * \brief Add a face struct to cache. |
213 * \param font font struct | 177 * \param font font struct |
214 */ | 178 */ |
215 void* ass_font_cache_add(ass_font_t* font) | 179 void *ass_font_cache_add(Hashmap *font_cache, ASS_Font *font) |
216 { | 180 { |
217 return hashmap_insert(font_cache, &(font->desc), font); | 181 return hashmap_insert(font_cache, &(font->desc), font); |
218 } | 182 } |
219 | 183 |
220 void ass_font_cache_init(void) | 184 Hashmap *ass_font_cache_init(ASS_Library *library) |
221 { | 185 { |
222 font_cache = hashmap_init(sizeof(ass_font_desc_t), | 186 Hashmap *font_cache; |
223 sizeof(ass_font_t), | 187 font_cache = hashmap_init(library, sizeof(ASS_FontDesc), |
224 1000, | 188 sizeof(ASS_Font), |
225 font_hash_dtor, font_compare, font_desc_hash); | 189 1000, |
226 } | 190 font_hash_dtor, font_compare, font_desc_hash); |
227 | 191 return font_cache; |
228 void ass_font_cache_done(void) | 192 } |
229 { | 193 |
230 hashmap_done(font_cache); | 194 void ass_font_cache_done(Hashmap *font_cache) |
231 } | 195 { |
196 hashmap_done(font_cache); | |
197 } | |
198 | |
199 | |
200 // Create hash/compare functions for bitmap and glyph | |
201 #define CREATE_HASH_FUNCTIONS | |
202 #include "ass_cache_template.h" | |
203 #define CREATE_COMPARISON_FUNCTIONS | |
204 #include "ass_cache_template.h" | |
232 | 205 |
233 //--------------------------------- | 206 //--------------------------------- |
234 // bitmap cache | 207 // bitmap cache |
235 | 208 |
236 hashmap_t* bitmap_cache; | 209 static void bitmap_hash_dtor(void *key, size_t key_size, void *value, |
237 | 210 size_t value_size) |
238 static void bitmap_hash_dtor(void* key, size_t key_size, void* value, size_t value_size) | 211 { |
239 { | 212 BitmapHashValue *v = value; |
240 bitmap_hash_val_t* v = value; | 213 if (v->bm) |
241 if (v->bm) ass_free_bitmap(v->bm); | 214 ass_free_bitmap(v->bm); |
242 if (v->bm_o) ass_free_bitmap(v->bm_o); | 215 if (v->bm_o) |
243 if (v->bm_s) ass_free_bitmap(v->bm_s); | 216 ass_free_bitmap(v->bm_o); |
244 free(key); | 217 if (v->bm_s) |
245 free(value); | 218 ass_free_bitmap(v->bm_s); |
246 } | 219 free(key); |
247 | 220 free(value); |
248 void* cache_add_bitmap(bitmap_hash_key_t* key, bitmap_hash_val_t* val) | 221 } |
249 { | 222 |
250 return hashmap_insert(bitmap_cache, key, val); | 223 void *cache_add_bitmap(Hashmap *bitmap_cache, BitmapHashKey *key, |
224 BitmapHashValue *val) | |
225 { | |
226 // Note: this is only an approximation | |
227 if (val->bm_o) | |
228 bitmap_cache->cache_size += val->bm_o->w * val->bm_o->h * 3; | |
229 else if (val->bm) | |
230 bitmap_cache->cache_size += val->bm->w * val->bm->h * 3; | |
231 | |
232 return hashmap_insert(bitmap_cache, key, val); | |
251 } | 233 } |
252 | 234 |
253 /** | 235 /** |
254 * \brief Get a bitmap from bitmap cache. | 236 * \brief Get a bitmap from bitmap cache. |
255 * \param key hash key | 237 * \param key hash key |
256 * \return requested hash val or 0 if not found | 238 * \return requested hash val or 0 if not found |
257 */ | 239 */ |
258 bitmap_hash_val_t* cache_find_bitmap(bitmap_hash_key_t* key) | 240 BitmapHashValue *cache_find_bitmap(Hashmap *bitmap_cache, |
259 { | 241 BitmapHashKey *key) |
260 return hashmap_find(bitmap_cache, key); | 242 { |
261 } | 243 return hashmap_find(bitmap_cache, key); |
262 | 244 } |
263 void ass_bitmap_cache_init(void) | 245 |
264 { | 246 Hashmap *ass_bitmap_cache_init(ASS_Library *library) |
265 bitmap_cache = hashmap_init(sizeof(bitmap_hash_key_t), | 247 { |
266 sizeof(bitmap_hash_val_t), | 248 Hashmap *bitmap_cache; |
267 0xFFFF + 13, | 249 bitmap_cache = hashmap_init(library, |
268 bitmap_hash_dtor, NULL, NULL); | 250 sizeof(BitmapHashKey), |
269 } | 251 sizeof(BitmapHashValue), |
270 | 252 0xFFFF + 13, |
271 void ass_bitmap_cache_done(void) | 253 bitmap_hash_dtor, bitmap_compare, |
272 { | 254 bitmap_hash); |
273 hashmap_done(bitmap_cache); | 255 return bitmap_cache; |
274 } | 256 } |
275 | 257 |
276 void ass_bitmap_cache_reset(void) | 258 void ass_bitmap_cache_done(Hashmap *bitmap_cache) |
277 { | 259 { |
278 ass_bitmap_cache_done(); | 260 hashmap_done(bitmap_cache); |
279 ass_bitmap_cache_init(); | 261 } |
262 | |
263 Hashmap *ass_bitmap_cache_reset(Hashmap *bitmap_cache) | |
264 { | |
265 ASS_Library *lib = bitmap_cache->library; | |
266 | |
267 ass_bitmap_cache_done(bitmap_cache); | |
268 return ass_bitmap_cache_init(lib); | |
280 } | 269 } |
281 | 270 |
282 //--------------------------------- | 271 //--------------------------------- |
283 // glyph cache | 272 // glyph cache |
284 | 273 |
285 hashmap_t* glyph_cache; | 274 static void glyph_hash_dtor(void *key, size_t key_size, void *value, |
286 | 275 size_t value_size) |
287 static void glyph_hash_dtor(void* key, size_t key_size, void* value, size_t value_size) | 276 { |
288 { | 277 GlyphHashValue *v = value; |
289 glyph_hash_val_t* v = value; | 278 if (v->glyph) |
290 if (v->glyph) FT_Done_Glyph(v->glyph); | 279 FT_Done_Glyph(v->glyph); |
291 if (v->outline_glyph) FT_Done_Glyph(v->outline_glyph); | 280 if (v->outline_glyph) |
292 free(key); | 281 FT_Done_Glyph(v->outline_glyph); |
293 free(value); | 282 free(key); |
294 } | 283 free(value); |
295 | 284 } |
296 void* cache_add_glyph(glyph_hash_key_t* key, glyph_hash_val_t* val) | 285 |
297 { | 286 void *cache_add_glyph(Hashmap *glyph_cache, GlyphHashKey *key, |
298 return hashmap_insert(glyph_cache, key, val); | 287 GlyphHashValue *val) |
288 { | |
289 return hashmap_insert(glyph_cache, key, val); | |
299 } | 290 } |
300 | 291 |
301 /** | 292 /** |
302 * \brief Get a glyph from glyph cache. | 293 * \brief Get a glyph from glyph cache. |
303 * \param key hash key | 294 * \param key hash key |
304 * \return requested hash val or 0 if not found | 295 * \return requested hash val or 0 if not found |
305 */ | 296 */ |
306 glyph_hash_val_t* cache_find_glyph(glyph_hash_key_t* key) | 297 GlyphHashValue *cache_find_glyph(Hashmap *glyph_cache, |
307 { | 298 GlyphHashKey *key) |
308 return hashmap_find(glyph_cache, key); | 299 { |
309 } | 300 return hashmap_find(glyph_cache, key); |
310 | 301 } |
311 void ass_glyph_cache_init(void) | 302 |
312 { | 303 Hashmap *ass_glyph_cache_init(ASS_Library *library) |
313 glyph_cache = hashmap_init(sizeof(glyph_hash_key_t), | 304 { |
314 sizeof(glyph_hash_val_t), | 305 Hashmap *glyph_cache; |
315 0xFFFF + 13, | 306 glyph_cache = hashmap_init(library, sizeof(GlyphHashKey), |
316 glyph_hash_dtor, NULL, NULL); | 307 sizeof(GlyphHashValue), |
317 } | 308 0xFFFF + 13, |
318 | 309 glyph_hash_dtor, glyph_compare, glyph_hash); |
319 void ass_glyph_cache_done(void) | 310 return glyph_cache; |
320 { | 311 } |
321 hashmap_done(glyph_cache); | 312 |
322 } | 313 void ass_glyph_cache_done(Hashmap *glyph_cache) |
323 | 314 { |
324 void ass_glyph_cache_reset(void) | 315 hashmap_done(glyph_cache); |
325 { | 316 } |
326 ass_glyph_cache_done(); | 317 |
327 ass_glyph_cache_init(); | 318 Hashmap *ass_glyph_cache_reset(Hashmap *glyph_cache) |
319 { | |
320 ASS_Library *lib = glyph_cache->library; | |
321 | |
322 ass_glyph_cache_done(glyph_cache); | |
323 return ass_glyph_cache_init(lib); | |
328 } | 324 } |
329 | 325 |
330 | 326 |
331 //--------------------------------- | 327 //--------------------------------- |
332 // composite cache | 328 // composite cache |
333 | 329 |
334 hashmap_t* composite_cache; | 330 static void composite_hash_dtor(void *key, size_t key_size, void *value, |
335 | 331 size_t value_size) |
336 static void composite_hash_dtor(void* key, size_t key_size, void* value, size_t value_size) | 332 { |
337 { | 333 CompositeHashValue *v = value; |
338 composite_hash_val_t* v = value; | 334 free(v->a); |
339 free(v->a); | 335 free(v->b); |
340 free(v->b); | 336 free(key); |
341 free(key); | 337 free(value); |
342 free(value); | 338 } |
343 } | 339 |
344 | 340 void *cache_add_composite(Hashmap *composite_cache, |
345 void* cache_add_composite(composite_hash_key_t* key, composite_hash_val_t* val) | 341 CompositeHashKey *key, |
346 { | 342 CompositeHashValue *val) |
347 return hashmap_insert(composite_cache, key, val); | 343 { |
344 return hashmap_insert(composite_cache, key, val); | |
348 } | 345 } |
349 | 346 |
350 /** | 347 /** |
351 * \brief Get a composite bitmap from composite cache. | 348 * \brief Get a composite bitmap from composite cache. |
352 * \param key hash key | 349 * \param key hash key |
353 * \return requested hash val or 0 if not found | 350 * \return requested hash val or 0 if not found |
354 */ | 351 */ |
355 composite_hash_val_t* cache_find_composite(composite_hash_key_t* key) | 352 CompositeHashValue *cache_find_composite(Hashmap *composite_cache, |
356 { | 353 CompositeHashKey *key) |
357 return hashmap_find(composite_cache, key); | 354 { |
358 } | 355 return hashmap_find(composite_cache, key); |
359 | 356 } |
360 void ass_composite_cache_init(void) | 357 |
361 { | 358 Hashmap *ass_composite_cache_init(ASS_Library *library) |
362 composite_cache = hashmap_init(sizeof(composite_hash_key_t), | 359 { |
363 sizeof(composite_hash_val_t), | 360 Hashmap *composite_cache; |
364 0xFFFF + 13, | 361 composite_cache = hashmap_init(library, sizeof(CompositeHashKey), |
365 composite_hash_dtor, NULL, NULL); | 362 sizeof(CompositeHashValue), |
366 } | 363 0xFFFF + 13, |
367 | 364 composite_hash_dtor, composite_compare, |
368 void ass_composite_cache_done(void) | 365 composite_hash); |
369 { | 366 return composite_cache; |
370 hashmap_done(composite_cache); | 367 } |
371 } | 368 |
372 | 369 void ass_composite_cache_done(Hashmap *composite_cache) |
373 void ass_composite_cache_reset(void) | 370 { |
374 { | 371 hashmap_done(composite_cache); |
375 ass_composite_cache_done(); | 372 } |
376 ass_composite_cache_init(); | 373 |
377 } | 374 Hashmap *ass_composite_cache_reset(Hashmap *composite_cache) |
378 | 375 { |
376 ASS_Library *lib = composite_cache->library; | |
377 | |
378 ass_composite_cache_done(composite_cache); | |
379 return ass_composite_cache_init(lib); | |
380 } |