diff options
author | Patrick Lam <plam@MIT.EDU> | 2005-07-25 04:10:09 +0000 |
---|---|---|
committer | Patrick Lam <plam@MIT.EDU> | 2005-07-25 04:10:09 +0000 |
commit | 212c9f437e959fbdc5fe344c67b8c1cf8ca63edb (patch) | |
tree | a5a82c8017ff6461dd8bdb4bb3e218af91b22ee6 /src/fcpat.c | |
parent | e1b9d091c661b0e1d1e9f73c5c55ad53959c55c7 (diff) |
#ifdef out old cache stuff, replace with first version of new mmapping
cache. Add *Read and *Write procedures which mmap in and write out the
fontconfig data structures to disk. Currently, create cache in /tmp,
with different sections for each architecture (as returned by uname's
.machine field. Run the fc-cache binary to create a new cache file;
fontconfig then uses this cache file on subsequent runs, saving lots of
memory. Also fixes a few bugs and leaks.
Diffstat (limited to 'src/fcpat.c')
-rw-r--r-- | src/fcpat.c | 241 |
1 files changed, 210 insertions, 31 deletions
diff --git a/src/fcpat.c b/src/fcpat.c index 0633c5ac..956ed669 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -94,8 +94,7 @@ FcValueSave (FcValue v) v.type = FcTypeVoid; break; case FcTypeCharSet: - v.u.ci = FcCharSetPtrCreateDynamic - (FcCharSetCopy (FcCharSetPtrU(v.u.ci))); + v.u.ci = FcCharSetCopyPtr (v.u.ci); if (!FcCharSetPtrU(v.u.ci)) v.type = FcTypeVoid; break; @@ -1270,7 +1269,6 @@ FcPatternEltU (FcPatternEltPtr pei) switch (pei.storage) { case FcStorageStatic: - if (pei.u.stat == 0) return 0; return &fcpatternelts[pei.u.stat]; case FcStorageDynamic: return pei.u.dyn; @@ -1324,6 +1322,8 @@ FcValueListClearStatic (void) fcvaluelist_count = 0; } +static FcBool +FcObjectPrepareSerialize (FcObjectPtr si); static FcObjectPtr FcObjectSerialize (FcObjectPtr si); @@ -1408,13 +1408,14 @@ FcPatternSerialize (FcPattern *old) fcpatternelt_ptr = 0; } - p = FcPatternCreate(); + p = &fcpatterns[fcpattern_ptr++]; elts = fcpatternelt_ptr; nep = &fcpatternelts[elts]; if (!nep) return FcFalse; + fcpatternelt_ptr += old->num; - + for (e = FcPatternEltU(old->elts), i=0; i < old->num; i++, e++) { v = e->values; @@ -1438,12 +1439,13 @@ FcPatternSerialize (FcPattern *old) } nep[i].values = nv_head; - nep[i].object = FcObjectSerialize - (FcObjectStaticName(FcObjectPtrU(e->object))); + nep[i].object = FcObjectSerialize (e->object); } - + + p->elts = old->elts; p->elts = FcPatternEltPtrCreateStatic(elts); p->size = old->num; + p->num = old->num; p->ref = FC_REF_CONSTANT; return p; @@ -1453,7 +1455,69 @@ FcPatternSerialize (FcPattern *old) free (fcpatterns); bail: return 0; - } +} + +FcBool +FcPatternRead (int fd, FcCache metadata) +{ + fcpatterns = mmap(NULL, + metadata.pattern_length * sizeof (FcPattern), + PROT_READ, + MAP_SHARED, fd, metadata.pattern_offset); + if (fcpatterns == MAP_FAILED) + return FcFalse; + fcpattern_count = fcpattern_ptr = metadata.pattern_length; + + return FcTrue; +} + +FcBool +FcPatternWrite (int fd, FcCache *metadata) +{ + int c = fcpattern_ptr; + off_t w = FcCacheNextOffset(fd); + + metadata->pattern_offset = w; + metadata->pattern_length = c; + + if (c > 0) + { + lseek(fd, w, SEEK_SET); + return write(fd, fcpatterns, c*sizeof(FcPattern)) != -1; + } + return FcTrue; +} + +FcBool +FcPatternEltRead (int fd, FcCache metadata) +{ + fcpatternelts = mmap(NULL, + metadata.patternelt_length * sizeof (FcPatternElt), + PROT_READ, + MAP_SHARED, fd, metadata.patternelt_offset); + if (fcpatternelts == MAP_FAILED) + return FcFalse; + fcpatternelt_count = fcpatternelt_ptr = metadata.patternelt_length; + + return FcTrue; +} + +FcBool +FcPatternEltWrite (int fd, FcCache *metadata) +{ + int c = fcpatternelt_ptr; + off_t w = FcCacheNextOffset(fd); + + metadata->patternelt_offset = w; + metadata->patternelt_length = c; + + if (c > 0) + { + lseek(fd, w, SEEK_SET); + return write(fd, fcpatternelts, c*sizeof(FcPatternElt)) != -1; + } + return FcTrue; +} FcValueListPtr FcValueListSerialize(FcValueList *pi) @@ -1480,13 +1544,18 @@ FcValueListSerialize(FcValueList *pi) switch (v->type) { case FcTypeString: - if (FcObjectPtrU(v->u.si)) + /* this departs from the usual convention of dereferencing + * foo before serialization; FcObjectSerialize does the + * translation itself. */ + /* also, v->u.si is 0 iff the string is null. */ + /* also, have to update the old pi */ + if (v->u.si) { - FcObjectPtr si = - FcObjectSerialize(FcObjectStaticName(FcObjectPtrU(v->u.si))); - if (!FcObjectPtrU(v->u.si)) + FcObjectPtr si = FcObjectSerialize(v->u.si); + if (!FcObjectPtrU(si)) return FcValueListPtrCreateDynamic(pi); v->u.si = si; + pi->value.u.si = si; } break; case FcTypeMatrix: @@ -1503,7 +1572,7 @@ FcValueListSerialize(FcValueList *pi) if (FcCharSetPtrU(v->u.ci)) { FcCharSetPtr ci = FcCharSetSerialize(FcCharSetPtrU(v->u.ci)); - if (!FcCharSetPtrU(v->u.ci)) + if (!FcCharSetPtrU(ci)) return FcValueListPtrCreateDynamic(pi); v->u.ci = ci; } @@ -1512,7 +1581,7 @@ FcValueListSerialize(FcValueList *pi) if (FcLangSetPtrU(v->u.li)) { FcLangSetPtr li = FcLangSetSerialize(FcLangSetPtrU(v->u.li)); - if (!FcLangSetPtrU(v->u.li)) + if (!FcLangSetPtrU(li)) return FcValueListPtrCreateDynamic(pi); v->u.li = li; } @@ -1523,13 +1592,41 @@ FcValueListSerialize(FcValueList *pi) return new; } +FcBool +FcValueListRead (int fd, FcCache metadata) +{ + fcvaluelists = mmap(NULL, + metadata.valuelist_length * sizeof (FcValueList), + PROT_READ, + MAP_SHARED, fd, metadata.valuelist_offset); + if (fcvaluelists == MAP_FAILED) + return FcFalse; + fcvaluelist_count = fcvaluelist_ptr = metadata.valuelist_length; + + return FcTrue; +} + +FcBool +FcValueListWrite (int fd, FcCache *metadata) +{ + metadata->valuelist_offset = FcCacheNextOffset(fd); + metadata->valuelist_length = fcvaluelist_ptr; + + if (fcvaluelist_ptr > 0) + { + lseek(fd, metadata->valuelist_offset, SEEK_SET); + return write(fd, fcvaluelists, + fcvaluelist_ptr * sizeof(FcValueList)) != -1; + } + return FcTrue; +} + FcValueList * FcValueListPtrU (FcValueListPtr pi) { switch (pi.storage) { case FcStorageStatic: - if (pi.u.stat == 0) return 0; return &fcvaluelists[pi.u.stat]; case FcStorageDynamic: return pi.u.dyn; @@ -1642,7 +1739,7 @@ FcObjectStaticName (const char *name) objectptr_alloc = s; } - size = sizeof (struct objectBucket) + strlen (name) + 1; + size = sizeof (struct objectBucket) + sizeof (char *); b = malloc (size); if (!b) return 0; @@ -1687,6 +1784,9 @@ FcObjectPtrDestroy (FcObjectPtr p) const char * FcObjectPtrU (FcObjectPtr si) { + if (si == 0) + return 0; + if (objectptr_indices[si] > 0) return &objectcontent_static_buf[objectptr_indices[si]]; else @@ -1750,7 +1850,7 @@ FcObjectRebuildStaticNameHashtable (void) /* Hmm. This will have a terrible effect on the memory size, * because the mmapped strings now get reallocated on the heap. * Is it all worth it? (Of course, the Serialization codepath is - * not problematic.) */ + * not problematic, because the program quits just afterwards.) */ static FcBool FcObjectPtrConvertToStatic(FcBool renumber) { @@ -1784,6 +1884,8 @@ FcObjectPtrConvertToStatic(FcBool renumber) new_indices = malloc (active_count * sizeof(int)); if (!new_indices) goto bail2; + new_indices[0] = 0; + new_static_buf[0] = 0; FcMemAlloc (FC_MEM_STATICSTR, new_static_bytes); FcMemFree (FC_MEM_STATICSTR, objectptr_count * sizeof (int)); @@ -1817,8 +1919,8 @@ FcObjectPtrConvertToStatic(FcBool renumber) int n = FcObjectStaticName(fixed_length_buf+i*(longest_string+1)); if (renumber) { - object_old_id_to_new[n] = i; - new_indices[i] = p-new_static_buf; + object_old_id_to_new[n] = i+1; + new_indices[i+1] = p-new_static_buf; } else new_indices[n] = p-new_static_buf; @@ -1907,21 +2009,11 @@ FcObjectClearStatic(void) object_old_id_to_new = 0; } -static FcObjectPtr -FcObjectSerialize (FcObjectPtr si) -{ - if (objectptr_first_serialization) - if (!FcObjectPtrConvertToStatic(FcTrue)) - return 0; - - return object_old_id_to_new[si]; -} - /* In the pre-serialization phase, mark the used strings with * -1 in the mapping array. */ /* The first call to the serialization phase assigns actual * static indices to the strings (sweep). */ -FcBool +static FcBool FcObjectPrepareSerialize (FcObjectPtr si) { if (object_old_id_to_new == 0) @@ -1942,6 +2034,93 @@ FcObjectPrepareSerialize (FcObjectPtr si) return FcFalse; } +static FcObjectPtr +FcObjectSerialize (FcObjectPtr si) +{ + if (objectptr_first_serialization) + if (!FcObjectPtrConvertToStatic(FcTrue)) + return 0; + + return object_old_id_to_new[si]; +} + +FcBool +FcObjectRead (int fd, FcCache metadata) +{ + /* do we have to merge strings? + * it's possible to merge dynamic strings, as long as we only store + * static strings to disk and as long as all static strings have lower + * ids than any dynamic strings. */ + + objectcontent_dynamic_count = 1; + objectcontent_dynamic_alloc = 0; + objectcontent_dynamic = 0; + objectcontent_dynamic_refcount = 0; + + /* well, we do need to allocate dynamic strings all the time, + * so this would just have to be converted. It takes 1.4k on + * my system. - PL */ +/* objectptr_indices = mmap(NULL, */ +/* metadata.object_length * sizeof (int), */ +/* PROT_READ, */ +/* MAP_SHARED, fd, metadata.object_offset); */ +/* if (objectptr_indices == MAP_FAILED) */ +/* goto bail; */ + + objectptr_count = metadata.object_length; + objectptr_alloc = metadata.object_length; + objectptr_indices = malloc (metadata.object_length * sizeof (int)); + if (!objectptr_indices) + goto bail; + FcMemAlloc (FC_MEM_STATICSTR, metadata.object_length * sizeof (int)); + lseek (fd, metadata.object_offset, SEEK_SET); + read (fd, objectptr_indices, metadata.object_length * sizeof (int)); + + objectcontent_static_buf = + mmap(NULL, + metadata.objectcontent_length * sizeof (char), + PROT_READ, + MAP_SHARED, fd, metadata.objectcontent_offset); + if (objectptr_indices == MAP_FAILED) + goto bail1; + objectcontent_static_bytes = metadata.objectcontent_length; + + FcObjectRebuildStaticNameHashtable (); + + return FcTrue; + + bail1: + /*munmap(objectptr_indices, metadata.object_length * sizeof(int));*/ + free (objectptr_indices); + bail: + return FcFalse; +} + +FcBool +FcObjectWrite (int fd, FcCache * metadata) +{ + /* there should be no dynamic strings: + * serialize ought to have zapped 'em. */ + if (objectcontent_dynamic_alloc) + return FcFalse; + + metadata->object_length = objectptr_count; + metadata->object_offset = FcCacheNextOffset(fd); + lseek(fd, metadata->object_offset, SEEK_SET); + if (write (fd, objectptr_indices, + metadata->object_length * sizeof (int)) == -1) + return FcFalse; + + metadata->objectcontent_length = objectcontent_static_bytes; + metadata->objectcontent_offset = FcCacheNextOffset(fd); + lseek(fd, metadata->objectcontent_offset, SEEK_SET); + if (write (fd, objectcontent_static_buf, + metadata->objectcontent_length * sizeof (char)) == -1) + return FcFalse; + + return FcTrue; +} + static void FcObjectStaticNameFini (void) { |