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;
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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -28,6 +28,7 @@
#include <stdio.h>
#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))

View File

@ -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