From: <ny...@us...> - 2007-01-26 13:27:26
|
Revision: 286 http://svn.sourceforge.net/pmplib/?rev=286&view=rev Author: nyaochi Date: 2007-01-26 05:27:21 -0800 (Fri, 26 Jan 2007) Log Message: ----------- [pmp_iriverplus3] Fixed three bugs in db.idx generation: - If two strings are identical by comparing without case, compare the strings again with case. - Avoid the region for a page header because avl_rewind() may move the offset to a start position of a page. - Do not dump an index whose root offset is 0, which means an empty member of the index. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-26 10:09:27 UTC (rev 285) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-26 13:27:21 UTC (rev 286) @@ -116,10 +116,16 @@ memset(avl->buffer + avl->size, 0, PAGESIZE); avl->offset = avl->size + sizeof(header_t); avl->size = newsize; - } else if (((avl->offset + size) / PAGESIZE) != (avl->offset / PAGESIZE)) { + } else { + int forward = 0; /* Avoid crossing a page boundary. */ - uint32_t page = (avl->offset + size) / PAGESIZE; - avl->offset = PAGESIZE * page + sizeof(header_t); + forward |= (((avl->offset + size - 1) / PAGESIZE) != (avl->offset / PAGESIZE)); + /* Avoid the region for a page header (caused by a rewind operation near a page boundary). */ + forward |= (avl->offset % PAGESIZE < sizeof(header_t)); + if (forward) { + uint32_t page = (avl->offset + size) / PAGESIZE; + avl->offset = PAGESIZE * page + sizeof(header_t); + } } /* Allocate a memory block. */ @@ -338,7 +344,7 @@ return str; } -static int avl_comp_ucs2string(avl_t* avl, uint32_t _x, uint32_t _y) +static int avl_comp_ucs2string_nocase(avl_t* avl, uint32_t _x, uint32_t _y) { ucs2char_t a, b; const ucs2char_t* x = (const ucs2char_t*)(avl->buffer + _x); @@ -359,6 +365,34 @@ return COMP(a, b); } +static int avl_comp_ucs2string(avl_t* avl, uint32_t _x, uint32_t _y) +{ + /* Compare strings, ignoring case. */ + int ret = avl_comp_ucs2string_nocase(avl, _x, _y); + if (ret == 0) { + /* Compare strings with case. */ + ucs2char_t a, b; + const ucs2char_t* x = (const ucs2char_t*)(avl->buffer + _x); + const ucs2char_t* y = (const ucs2char_t*)(avl->buffer + _y); + + x = skip_prefix(x); + y = skip_prefix(y); + + do { + a = *x; + b = *y; + if (!*x || !*y) { + break; + } + x++; + y++; + } while (a == b); + return COMP(a, b); + } else { + return ret; + } +} + static int avl_insert_key(avl_t* avl, const ip3db_variant_t* key, int type, uint32_t* offset, uint32_t* root) { int ret = 0; @@ -774,7 +808,9 @@ fprintf(fpo, "["); dic_repr_index(dic, IP3DBIDX_MUSIC, i, fpo); fprintf(fpo, "]\n"); - avl_dump(idx->avl, idx_root, &dic->music, i, 0, fpo); + if (idx_root) { + avl_dump(idx->avl, idx_root, &dic->music, i, 0, fpo); + } } for (i = 0;i < dic->references.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); @@ -790,7 +826,9 @@ fprintf(fpo, "["); dic_repr_index(dic, IP3DBIDX_OBJECTS, i, fpo); fprintf(fpo, "]\n"); - avl_dump(idx->avl, idx_root, &dic->objects, i, 0, fpo); + if (idx_root) { + avl_dump(idx->avl, idx_root, &dic->objects, i, 0, fpo); + } } fprintf(fpo, "\n"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |