From 7f37423d8c1acc8ece0555e66ae7f857c22a77a7 Mon Sep 17 00:00:00 2001 From: Patrick Lam Date: Sat, 27 Aug 2005 02:34:24 +0000 Subject: [PATCH] Replace FcObjectStaticName by FcStrStaticName. Implement serialization of 'object' table (strings pointed to by FcPatternElt->object and used as keys) and loading of object table from cache file if more strings are present in cache file than in current version of fontconfig. Hash the object table in memory. --- src/fccfg.c | 4 +- src/fcfs.c | 11 ++-- src/fcint.h | 31 +++++---- src/fclist.c | 2 +- src/fcname.c | 181 ++++++++++++++++++++++++++++++++++++++++++--------- src/fcpat.c | 19 +++--- 6 files changed, 186 insertions(+), 62 deletions(-) diff --git a/src/fccfg.c b/src/fccfg.c index 4d2e024..0032a9b 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -773,7 +773,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) break; case FcOpString: v.type = FcTypeString; - v.u.s = FcObjectStaticName(e->u.sval); + v.u.s = FcStrStaticName(e->u.sval); v = FcValueSave (v); break; case FcOpMatrix: @@ -891,7 +891,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) switch (e->op) { case FcOpPlus: v.type = FcTypeString; - v.u.s = FcObjectStaticName (FcStrPlus (vl.u.s, vr.u.s)); + v.u.s = FcStrStaticName (FcStrPlus (vl.u.s, vr.u.s)); if (!v.u.s) v.type = FcTypeVoid; diff --git a/src/fcfs.c b/src/fcfs.c index 1e5aa81..90e8580 100644 --- a/src/fcfs.c +++ b/src/fcfs.c @@ -87,7 +87,6 @@ void FcFontSetNewBank (void) { FcPatternNewBank(); - FcObjectNewBank(); } int @@ -104,7 +103,7 @@ FcFontSetNeededBytes (FcFontSet *s) } if (cum > 0) - return cum + sizeof(int); + return cum + sizeof(int) + FcObjectNeededBytes(); else return 0; } @@ -138,6 +137,7 @@ FcFontSetSerialize (int bank, FcFontSet * s) s->fonts[i] = p; } + FcObjectSerialize(); return FcTrue; } @@ -166,10 +166,13 @@ FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr) if (nfont > 0) { - FcPattern * p = FcPatternUnserialize (metadata, block_ptr); + FcPattern * p = (FcPattern *)block_ptr; + block_ptr = FcPatternUnserialize (metadata, block_ptr); for (i = 0; i < nfont; i++) s->fonts[n + i] = p+i; + + block_ptr = FcObjectUnserialize (metadata, block_ptr); } - return FcTrue; + return block_ptr != 0; } diff --git a/src/fcint.h b/src/fcint.h index 73039f4..446e164 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -808,9 +808,6 @@ FcListPatternMatchAny (const FcPattern *p, FcBool FcNameBool (const FcChar8 *v, FcBool *result); -void -FcObjectNewBank(void); - void * FcObjectDistributeBytes (FcCache * metadata, void * block_ptr); @@ -819,13 +816,22 @@ FcObjectPtr FcObjectToPtr (const char * si); int -FcObjectNeededBytes (FcObjectPtr p); +FcObjectNeededBytes (void); + +void * +FcObjectUnserialize (FcCache metadata, void *block_ptr); void -FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr); +FcObjectSerialize (void); -FcObjectPtr -FcObjectSerialize (FcObjectPtr s); +const char * +FcObjectPtrU (FcObjectPtr p); + +int +FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b); + +void +FcObjectStaticNameFini (void); /* fcpat.c */ @@ -858,13 +864,10 @@ FcBool FcPatternAppend (FcPattern *p, FcPattern *s); const char * -FcObjectStaticName (const char *name); +FcStrStaticName (const char *name); -const char * -FcObjectPtrU (FcObjectPtr p); - -int -FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b); +FcChar32 +FcStringHash (const FcChar8 *s); void FcPatternNewBank (void); @@ -887,7 +890,7 @@ FcValueListPtrCreateDynamic(FcValueList * p); FcPattern * FcPatternSerialize (int bank, FcPattern * p); -FcPattern * +void * FcPatternUnserialize (FcCache metadata, void *block_ptr); /* fcrender.c */ diff --git a/src/fclist.c b/src/fclist.c index db63058..02ef877 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -67,7 +67,7 @@ FcObjectSetAdd (FcObjectSet *os, const char *object) low = 0; mid = 0; c = 1; - object = FcObjectStaticName (object); + object = FcStrStaticName (object); while (low <= high) { mid = (low + high) >> 1; diff --git a/src/fcname.c b/src/fcname.c index 1cdba56..e50f75f 100644 --- a/src/fcname.c +++ b/src/fcname.c @@ -28,6 +28,7 @@ #include #include "fcint.h" +/* Please do not revoke any of these bindings. */ static const FcObjectType _FcBaseObjectTypes[] = { { FC_FAMILY, FcTypeString, }, { FC_FAMILYLANG, FcTypeString, }, @@ -106,8 +107,9 @@ FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes) return FcTrue; } -FcBool -FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) +static FcBool +FcNameUnregisterObjectTypesFree (const FcObjectType *types, int ntypes, + FcBool do_free) { const FcObjectTypeList *l, **prev; @@ -118,14 +120,22 @@ FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) if (l->types == types && l->ntypes == ntypes) { *prev = l->next; - FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList)); - free ((void *) l); + if (do_free) { + FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList)); + free ((void *) l); + } return FcTrue; } } return FcFalse; } +FcBool +FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) +{ + return FcNameUnregisterObjectTypesFree (types, ntypes, FcTrue); +} + const FcObjectType * FcNameGetObjectType (const char *object) { @@ -145,26 +155,13 @@ FcNameGetObjectType (const char *object) return 0; } -static int objectptr_count = 1; -static int objectptr_alloc = 0; -static int * objectptr_indices = 0; - -void -FcObjectNewBank(void) +static FcObjectPtr +FcObjectToPtrLookup (const char * object) { - objectptr_count = 1; - objectptr_alloc = 0; - objectptr_indices = 0; -} - -// XXX todo: introduce a hashtable for faster lookup -FcObjectPtr -FcObjectToPtr (const char * object) -{ - int i; + FcObjectPtr i; const FcObjectTypeList *l; const FcObjectType *t; - + for (l = _FcObjectTypes; l; l = l->next) { for (i = 0; i < l->ntypes; i++) @@ -174,37 +171,159 @@ FcObjectToPtr (const char * object) return i; } } - abort(); return 0; } +#define OBJECT_HASH_SIZE 31 +struct objectBucket { + struct objectBucket *next; + FcChar32 hash; + int id; +}; +static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; + +static const FcObjectType *biggest_known_types = _FcBaseObjectTypes; +static FcBool allocated_biggest_known_types; +static int biggest_known_ntypes = NUM_OBJECT_TYPES; +static int biggest_known_count = 0; +static char * biggest_ptr; + +FcObjectPtr +FcObjectToPtr (const char * name) +{ + FcChar32 hash = FcStringHash ((const FcChar8 *) name); + struct objectBucket **p; + struct objectBucket *b; + int size; + + for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next) +) + if (b->hash == hash && !strcmp (name, (char *) (b + 1))) + return b->id; + size = sizeof (struct objectBucket) + strlen (name) + 1; + b = malloc (size); + FcMemAlloc (FC_MEM_STATICSTR, size); + if (!b) + return -1; + b->next = 0; + b->hash = hash; + b->id = FcObjectToPtrLookup (name); + strcpy ((char *) (b + 1), name); + *p = b; + return b->id; +} + +void +FcObjectStaticNameFini (void) +{ + int i, size; + struct objectBucket *b, *next; + char *name; + + for (i = 0; i < OBJECT_HASH_SIZE; i++) + { + for (b = FcObjectBuckets[i]; b; b = next) + { + next = b->next; + name = (char *) (b + 1); + size = sizeof (struct objectBucket) + strlen (name) + 1; + FcMemFree (FC_MEM_STATICSTR, size); + free (b); + } + FcObjectBuckets[i] = 0; + } +} + const char * FcObjectPtrU (FcObjectPtr si) { - return _FcObjectTypes->types[si].object; + return biggest_known_types[si].object; } int -FcObjectNeededBytes (FcObjectPtr si) +FcObjectNeededBytes () { - return 0; + int num = 0, i; + for (i = 0; i < biggest_known_ntypes; i++) + { + const char * t = biggest_known_types[i].object; + num = num + strlen(t) + 1; + } + biggest_known_count = num; + return num + sizeof(int); } void * FcObjectDistributeBytes (FcCache * metadata, void * block_ptr) { + *(int *)block_ptr = biggest_known_ntypes; + block_ptr = (int *) block_ptr + 1; + biggest_ptr = block_ptr; + block_ptr = (char *) block_ptr + biggest_known_count; return block_ptr; } -FcObjectPtr -FcObjectSerialize (FcObjectPtr si) +void +FcObjectSerialize () { - return si; + int i; + for (i = 0; i < biggest_known_ntypes; i++) + { + const char * t = biggest_known_types[i].object; + strcpy (biggest_ptr, t); + biggest_ptr = biggest_ptr + strlen(t) + 1; + } } -void -FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr) +void * +FcObjectUnserialize (FcCache metadata, void *block_ptr) { + int new_biggest; + new_biggest = *(int *)block_ptr; + block_ptr = (int *) block_ptr + 1; + if (biggest_known_ntypes < new_biggest) + { + int i; + char * bp = (char *)block_ptr; + FcObjectType * bn; + FcObjectTypeList * bnl; + + bn = malloc (sizeof (const FcObjectType) * (new_biggest + 1)); + if (!bn) + return 0; + + bnl = malloc (sizeof (FcObjectTypeList)); + if (!bnl) + { + free (bn); + return 0; + } + + for (i = 0; i < new_biggest; i++) + { + const FcObjectType * t = FcNameGetObjectType(bp); + if (t) + bn[i].type = t->type; + else + bn[i].type = FcTypeVoid; + bn[i].object = bp; + bp = bp + strlen(bp) + 1; + } + + FcNameUnregisterObjectTypesFree (biggest_known_types, biggest_known_ntypes, FcFalse); + if (allocated_biggest_known_types) + { + free ((FcObjectTypeList *)biggest_known_types); + } + else + allocated_biggest_known_types = FcTrue; + + FcNameRegisterObjectTypes (bn, new_biggest); + biggest_known_ntypes = new_biggest; + biggest_known_types = (const FcObjectType *)bn; + } + block_ptr = (char *) block_ptr + biggest_known_count; + return block_ptr; } int @@ -389,7 +508,7 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m) v.u.i = atoi ((char *) string); break; case FcTypeString: - v.u.s = FcObjectStaticName(string); + v.u.s = FcStrStaticName(string); break; case FcTypeBool: if (!FcNameBool (string, &v.u.b)) diff --git a/src/fcpat.c b/src/fcpat.c index d42401d..e3f244a 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -214,7 +214,7 @@ FcDoubleHash (double d) return (FcChar32) d; } -static FcChar32 +FcChar32 FcStringHash (const FcChar8 *s) { FcChar8 c; @@ -391,7 +391,7 @@ FcValueListEntCreate (FcValueListPtr h) if ((FcValueListPtrU(l)->value.type & ~FC_STORAGE_STATIC) == FcTypeString) { new->value.type = FcTypeString; - new->value.u.s = FcObjectStaticName + new->value.u.s = FcStrStaticName (fc_value_string(&FcValueListPtrU(l)->value)); } else @@ -984,7 +984,7 @@ FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s) FcValue v; v.type = FcTypeString; - v.u.s = FcObjectStaticName(s); + v.u.s = FcStrStaticName(s); return FcPatternAdd (p, object, v, FcTrue); } @@ -1287,7 +1287,7 @@ struct objectBucket { static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; const char * -FcObjectStaticName (const char *name) +FcStrStaticName (const char *name) { FcChar32 hash = FcStringHash ((const FcChar8 *) name); struct objectBucket **p; @@ -1311,7 +1311,7 @@ FcObjectStaticName (const char *name) } static void -FcObjectStaticNameFini (void) +FcStrStaticNameFini (void) { int i, size; struct objectBucket *b, *next; @@ -1336,6 +1336,7 @@ FcPatternFini (void) { FcPatternBaseThawAll (); FcValueListThawAll (); + FcStrStaticNameFini (); FcObjectStaticNameFini (); } @@ -1409,8 +1410,6 @@ FcPatternNeededBytes (FcPattern * p) for (i = 0; i < p->num; i++) { - cum += FcObjectNeededBytes - ((FcPatternEltU(p->elts)+i)->object); c = FcValueListNeededBytes (FcValueListPtrU (((FcPatternEltU(p->elts)+i)->values))); if (c < 0) @@ -1526,7 +1525,7 @@ FcPatternSerialize (int bank, FcPattern *old) } nep[i].values = nv_head; - nep[i].object = FcObjectSerialize (e->object); + nep[i].object = e->object; } p->elts = old->elts; @@ -1537,7 +1536,7 @@ FcPatternSerialize (int bank, FcPattern *old) return p; } -FcPattern * +void * FcPatternUnserialize (FcCache metadata, void *block_ptr) { int bi = FcCacheBankToIndex(metadata.bank); @@ -1558,7 +1557,7 @@ FcPatternUnserialize (FcCache metadata, void *block_ptr) block_ptr = FcStrUnserialize (metadata, block_ptr); block_ptr = FcValueListUnserialize (metadata, block_ptr); - return fcpatterns[bi]; + return block_ptr; } static void