diff --git a/geojson.c b/geojson.c index 1863c5a3..d43b0db2 100644 --- a/geojson.c +++ b/geojson.c @@ -395,17 +395,22 @@ static void merge(struct merge *merges, int nmerges, unsigned char *map, FILE *f } struct stringpool { - char *s; + char *s; // first byte is type struct stringpool *left; struct stringpool *right; long long off; } *pooltree = NULL; -long long addpool(FILE *poolfile, long long *poolpos, char *s) { +long long addpool(FILE *poolfile, long long *poolpos, char *s, char type) { struct stringpool **sp = &pooltree; while (*sp != NULL) { - int cmp = strcmp(s, (*sp)->s); + int cmp = strcmp(s, (*sp)->s + 1); + + if (cmp == 0) { + cmp = type - (*sp)->s[0]; + } + if (cmp < 0) { sp = &((*sp)->left); } else if (cmp > 0) { @@ -416,13 +421,15 @@ long long addpool(FILE *poolfile, long long *poolpos, char *s) { } *sp = malloc(sizeof(struct stringpool)); - (*sp)->s = strdup(s); // XXX really should be mapped from the pool itself + (*sp)->s = malloc(strlen(s) + 2); + (*sp)->s[0] = type; + strcpy((*sp)->s + 1, s); // XXX really should be mapped from the pool itself (*sp)->left = NULL; (*sp)->right = NULL; (*sp)->off = *poolpos; - fwrite_check(s, strlen(s) + 1, sizeof(char), poolfile, "string pool"); - *poolpos += strlen(s) + 1; + fwrite_check((*sp)->s, strlen(s) + 2, sizeof(char), poolfile, "string pool"); + *poolpos += strlen(s) + 2; return (*sp)->off; } @@ -655,9 +662,8 @@ int read_json(int argc, char **argv, char *fname, const char *layername, int max serialize_int(metafile, m, &metapos, fname); for (i = 0; i < m; i++) { - serialize_int(metafile, metatype[i], &metapos, fname); - serialize_long_long(metafile, addpool(poolfile, &poolpos, metakey[i]), &metapos, fname); - serialize_long_long(metafile, addpool(poolfile, &poolpos, metaval[i]), &metapos, fname); + serialize_long_long(metafile, addpool(poolfile, &poolpos, metakey[i], VT_STRING), &metapos, fname); + serialize_long_long(metafile, addpool(poolfile, &poolpos, metaval[i], metatype[i]), &metapos, fname); } long long geomstart = geompos; diff --git a/tile.cc b/tile.cc index 12791c32..2877da45 100644 --- a/tile.cc +++ b/tile.cc @@ -186,12 +186,12 @@ int coalindexcmp(const struct coalesce *c1, const struct coalesce *c2) { return cmp; } -struct pool_val *retrieve_string(char **f, struct pool *p, int type, char *stringpool) { +struct pool_val *retrieve_string(char **f, struct pool *p, char *stringpool) { struct pool_val *ret; long long off; deserialize_long_long(f, &off); - ret = pool(p, stringpool + off, type); + ret = pool(p, stringpool + off + 1, stringpool[off]); return ret; } @@ -202,22 +202,20 @@ void decode_meta(char **meta, char *stringpool, struct pool *keys, struct pool * int i; for (i = 0; i < m; i++) { - int t; - deserialize_int(meta, &t); - struct pool_val *key = retrieve_string(meta, keys, VT_STRING, stringpool); + struct pool_val *key = retrieve_string(meta, keys, stringpool); if (only != NULL && (strcmp(key->s, only) != 0)) { - deserialize_int(meta, &t); - *meta += t; + // XXX if evaluate ever works again, check whether this is sufficient + (void) retrieve_string(meta, values, stringpool); } else { - struct pool_val *value = retrieve_string(meta, values, t, stringpool); + struct pool_val *value = retrieve_string(meta, values, stringpool); intmeta->push_back(key->n); intmeta->push_back(value->n); - if (!is_pooled(file_keys, key->s, t)) { + if (!is_pooled(file_keys, key->s, value->type)) { // Dup to retain after munmap - pool(file_keys, strdup(key->s), t); + pool(file_keys, strdup(key->s), value->type); } } }