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.
This commit is contained in:
Patrick Lam 2005-08-27 02:34:24 +00:00
parent 1b7be37790
commit 7f37423d8c
6 changed files with 186 additions and 62 deletions

View File

@ -773,7 +773,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break; break;
case FcOpString: case FcOpString:
v.type = FcTypeString; v.type = FcTypeString;
v.u.s = FcObjectStaticName(e->u.sval); v.u.s = FcStrStaticName(e->u.sval);
v = FcValueSave (v); v = FcValueSave (v);
break; break;
case FcOpMatrix: case FcOpMatrix:
@ -891,7 +891,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
switch (e->op) { switch (e->op) {
case FcOpPlus: case FcOpPlus:
v.type = FcTypeString; 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) if (!v.u.s)
v.type = FcTypeVoid; v.type = FcTypeVoid;

View File

@ -87,7 +87,6 @@ void
FcFontSetNewBank (void) FcFontSetNewBank (void)
{ {
FcPatternNewBank(); FcPatternNewBank();
FcObjectNewBank();
} }
int int
@ -104,7 +103,7 @@ FcFontSetNeededBytes (FcFontSet *s)
} }
if (cum > 0) if (cum > 0)
return cum + sizeof(int); return cum + sizeof(int) + FcObjectNeededBytes();
else else
return 0; return 0;
} }
@ -138,6 +137,7 @@ FcFontSetSerialize (int bank, FcFontSet * s)
s->fonts[i] = p; s->fonts[i] = p;
} }
FcObjectSerialize();
return FcTrue; return FcTrue;
} }
@ -166,10 +166,13 @@ FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr)
if (nfont > 0) 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++) for (i = 0; i < nfont; i++)
s->fonts[n + i] = p+i; s->fonts[n + i] = p+i;
block_ptr = FcObjectUnserialize (metadata, block_ptr);
} }
return FcTrue; return block_ptr != 0;
} }

View File

@ -808,9 +808,6 @@ FcListPatternMatchAny (const FcPattern *p,
FcBool FcBool
FcNameBool (const FcChar8 *v, FcBool *result); FcNameBool (const FcChar8 *v, FcBool *result);
void
FcObjectNewBank(void);
void * void *
FcObjectDistributeBytes (FcCache * metadata, FcObjectDistributeBytes (FcCache * metadata,
void * block_ptr); void * block_ptr);
@ -819,13 +816,22 @@ FcObjectPtr
FcObjectToPtr (const char * si); FcObjectToPtr (const char * si);
int int
FcObjectNeededBytes (FcObjectPtr p); FcObjectNeededBytes (void);
void *
FcObjectUnserialize (FcCache metadata, void *block_ptr);
void void
FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr); FcObjectSerialize (void);
FcObjectPtr const char *
FcObjectSerialize (FcObjectPtr s); FcObjectPtrU (FcObjectPtr p);
int
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
void
FcObjectStaticNameFini (void);
/* fcpat.c */ /* fcpat.c */
@ -858,13 +864,10 @@ FcBool
FcPatternAppend (FcPattern *p, FcPattern *s); FcPatternAppend (FcPattern *p, FcPattern *s);
const char * const char *
FcObjectStaticName (const char *name); FcStrStaticName (const char *name);
const char * FcChar32
FcObjectPtrU (FcObjectPtr p); FcStringHash (const FcChar8 *s);
int
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
void void
FcPatternNewBank (void); FcPatternNewBank (void);
@ -887,7 +890,7 @@ FcValueListPtrCreateDynamic(FcValueList * p);
FcPattern * FcPattern *
FcPatternSerialize (int bank, FcPattern * p); FcPatternSerialize (int bank, FcPattern * p);
FcPattern * void *
FcPatternUnserialize (FcCache metadata, void *block_ptr); FcPatternUnserialize (FcCache metadata, void *block_ptr);
/* fcrender.c */ /* fcrender.c */

View File

@ -67,7 +67,7 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
low = 0; low = 0;
mid = 0; mid = 0;
c = 1; c = 1;
object = FcObjectStaticName (object); object = FcStrStaticName (object);
while (low <= high) while (low <= high)
{ {
mid = (low + high) >> 1; mid = (low + high) >> 1;

View File

@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include "fcint.h" #include "fcint.h"
/* Please do not revoke any of these bindings. */
static const FcObjectType _FcBaseObjectTypes[] = { static const FcObjectType _FcBaseObjectTypes[] = {
{ FC_FAMILY, FcTypeString, }, { FC_FAMILY, FcTypeString, },
{ FC_FAMILYLANG, FcTypeString, }, { FC_FAMILYLANG, FcTypeString, },
@ -106,8 +107,9 @@ FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
return FcTrue; return FcTrue;
} }
FcBool static FcBool
FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes) FcNameUnregisterObjectTypesFree (const FcObjectType *types, int ntypes,
FcBool do_free)
{ {
const FcObjectTypeList *l, **prev; const FcObjectTypeList *l, **prev;
@ -118,14 +120,22 @@ FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
if (l->types == types && l->ntypes == ntypes) if (l->types == types && l->ntypes == ntypes)
{ {
*prev = l->next; *prev = l->next;
FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList)); if (do_free) {
free ((void *) l); FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
free ((void *) l);
}
return FcTrue; return FcTrue;
} }
} }
return FcFalse; return FcFalse;
} }
FcBool
FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
{
return FcNameUnregisterObjectTypesFree (types, ntypes, FcTrue);
}
const FcObjectType * const FcObjectType *
FcNameGetObjectType (const char *object) FcNameGetObjectType (const char *object)
{ {
@ -145,26 +155,13 @@ FcNameGetObjectType (const char *object)
return 0; return 0;
} }
static int objectptr_count = 1; static FcObjectPtr
static int objectptr_alloc = 0; FcObjectToPtrLookup (const char * object)
static int * objectptr_indices = 0;
void
FcObjectNewBank(void)
{ {
objectptr_count = 1; FcObjectPtr i;
objectptr_alloc = 0;
objectptr_indices = 0;
}
// XXX todo: introduce a hashtable for faster lookup
FcObjectPtr
FcObjectToPtr (const char * object)
{
int i;
const FcObjectTypeList *l; const FcObjectTypeList *l;
const FcObjectType *t; const FcObjectType *t;
for (l = _FcObjectTypes; l; l = l->next) for (l = _FcObjectTypes; l; l = l->next)
{ {
for (i = 0; i < l->ntypes; i++) for (i = 0; i < l->ntypes; i++)
@ -174,37 +171,159 @@ FcObjectToPtr (const char * object)
return i; return i;
} }
} }
abort();
return 0; 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 * const char *
FcObjectPtrU (FcObjectPtr si) FcObjectPtrU (FcObjectPtr si)
{ {
return _FcObjectTypes->types[si].object; return biggest_known_types[si].object;
} }
int 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 * void *
FcObjectDistributeBytes (FcCache * metadata, void * block_ptr) 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; return block_ptr;
} }
FcObjectPtr void
FcObjectSerialize (FcObjectPtr si) 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 void *
FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr) 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 int
@ -389,7 +508,7 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
v.u.i = atoi ((char *) string); v.u.i = atoi ((char *) string);
break; break;
case FcTypeString: case FcTypeString:
v.u.s = FcObjectStaticName(string); v.u.s = FcStrStaticName(string);
break; break;
case FcTypeBool: case FcTypeBool:
if (!FcNameBool (string, &v.u.b)) if (!FcNameBool (string, &v.u.b))

View File

@ -214,7 +214,7 @@ FcDoubleHash (double d)
return (FcChar32) d; return (FcChar32) d;
} }
static FcChar32 FcChar32
FcStringHash (const FcChar8 *s) FcStringHash (const FcChar8 *s)
{ {
FcChar8 c; FcChar8 c;
@ -391,7 +391,7 @@ FcValueListEntCreate (FcValueListPtr h)
if ((FcValueListPtrU(l)->value.type & ~FC_STORAGE_STATIC) == FcTypeString) if ((FcValueListPtrU(l)->value.type & ~FC_STORAGE_STATIC) == FcTypeString)
{ {
new->value.type = FcTypeString; new->value.type = FcTypeString;
new->value.u.s = FcObjectStaticName new->value.u.s = FcStrStaticName
(fc_value_string(&FcValueListPtrU(l)->value)); (fc_value_string(&FcValueListPtrU(l)->value));
} }
else else
@ -984,7 +984,7 @@ FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
FcValue v; FcValue v;
v.type = FcTypeString; v.type = FcTypeString;
v.u.s = FcObjectStaticName(s); v.u.s = FcStrStaticName(s);
return FcPatternAdd (p, object, v, FcTrue); return FcPatternAdd (p, object, v, FcTrue);
} }
@ -1287,7 +1287,7 @@ struct objectBucket {
static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE]; static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
const char * const char *
FcObjectStaticName (const char *name) FcStrStaticName (const char *name)
{ {
FcChar32 hash = FcStringHash ((const FcChar8 *) name); FcChar32 hash = FcStringHash ((const FcChar8 *) name);
struct objectBucket **p; struct objectBucket **p;
@ -1311,7 +1311,7 @@ FcObjectStaticName (const char *name)
} }
static void static void
FcObjectStaticNameFini (void) FcStrStaticNameFini (void)
{ {
int i, size; int i, size;
struct objectBucket *b, *next; struct objectBucket *b, *next;
@ -1336,6 +1336,7 @@ FcPatternFini (void)
{ {
FcPatternBaseThawAll (); FcPatternBaseThawAll ();
FcValueListThawAll (); FcValueListThawAll ();
FcStrStaticNameFini ();
FcObjectStaticNameFini (); FcObjectStaticNameFini ();
} }
@ -1409,8 +1410,6 @@ FcPatternNeededBytes (FcPattern * p)
for (i = 0; i < p->num; i++) for (i = 0; i < p->num; i++)
{ {
cum += FcObjectNeededBytes
((FcPatternEltU(p->elts)+i)->object);
c = FcValueListNeededBytes (FcValueListPtrU c = FcValueListNeededBytes (FcValueListPtrU
(((FcPatternEltU(p->elts)+i)->values))); (((FcPatternEltU(p->elts)+i)->values)));
if (c < 0) if (c < 0)
@ -1526,7 +1525,7 @@ FcPatternSerialize (int bank, FcPattern *old)
} }
nep[i].values = nv_head; nep[i].values = nv_head;
nep[i].object = FcObjectSerialize (e->object); nep[i].object = e->object;
} }
p->elts = old->elts; p->elts = old->elts;
@ -1537,7 +1536,7 @@ FcPatternSerialize (int bank, FcPattern *old)
return p; return p;
} }
FcPattern * void *
FcPatternUnserialize (FcCache metadata, void *block_ptr) FcPatternUnserialize (FcCache metadata, void *block_ptr)
{ {
int bi = FcCacheBankToIndex(metadata.bank); int bi = FcCacheBankToIndex(metadata.bank);
@ -1558,7 +1557,7 @@ FcPatternUnserialize (FcCache metadata, void *block_ptr)
block_ptr = FcStrUnserialize (metadata, block_ptr); block_ptr = FcStrUnserialize (metadata, block_ptr);
block_ptr = FcValueListUnserialize (metadata, block_ptr); block_ptr = FcValueListUnserialize (metadata, block_ptr);
return fcpatterns[bi]; return block_ptr;
} }
static void static void