ICU-4084 Improve doOpenChoice performance.
X-SVN-Rev: 16444
This commit is contained in:
parent
4fbf096779
commit
cf3b69cbf1
@ -104,7 +104,8 @@ offsetTOCLookupFn(const UDataMemory *pData,
|
|||||||
const UDataOffsetTOC *toc = (UDataOffsetTOC *)pData->toc;
|
const UDataOffsetTOC *toc = (UDataOffsetTOC *)pData->toc;
|
||||||
if(toc!=NULL) {
|
if(toc!=NULL) {
|
||||||
const char *base=(const char *)pData->toc;
|
const char *base=(const char *)pData->toc;
|
||||||
uint32_t start, limit, number;
|
uint32_t start, limit, number, lastNumber;
|
||||||
|
int32_t strResult;
|
||||||
|
|
||||||
/* perform a binary search for the data in the common data's table of contents */
|
/* perform a binary search for the data in the common data's table of contents */
|
||||||
#if defined (UDATA_DEBUG_DUMP)
|
#if defined (UDATA_DEBUG_DUMP)
|
||||||
@ -116,36 +117,40 @@ offsetTOCLookupFn(const UDataMemory *pData,
|
|||||||
|
|
||||||
start=0;
|
start=0;
|
||||||
limit=toc->count; /* number of names in this table of contents */
|
limit=toc->count; /* number of names in this table of contents */
|
||||||
|
lastNumber=limit;
|
||||||
if (limit == 0) { /* Stub common data library used during build is empty. */
|
if (limit == 0) { /* Stub common data library used during build is empty. */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
while(start<limit-1) {
|
for (;;) {
|
||||||
number=(start+limit)/2;
|
number = (start+limit)/2;
|
||||||
if(uprv_strcmp(tocEntryName, &base[toc->entry[number].nameOffset])<0) {
|
if (lastNumber == number) { /* Have we moved? */
|
||||||
|
break; /* We haven't moved, and it wasn't found. */
|
||||||
|
}
|
||||||
|
lastNumber = number;
|
||||||
|
strResult = uprv_strcmp(tocEntryName, &base[toc->entry[number].nameOffset]);
|
||||||
|
if(strResult<0) {
|
||||||
limit=number;
|
limit=number;
|
||||||
} else {
|
} else if (strResult>0) {
|
||||||
start=number;
|
start=number;
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
/* found it */
|
||||||
if(uprv_strcmp(tocEntryName, &base[toc->entry[start].nameOffset])==0) {
|
|
||||||
/* found it */
|
|
||||||
#ifdef UDATA_DEBUG
|
#ifdef UDATA_DEBUG
|
||||||
/* fprintf(stderr, "Found: %p\n",(base+toc[2*start+1])); */
|
/* fprintf(stderr, "Found: %p\n",(base+toc[2*start+1])); */
|
||||||
fprintf(stderr, "%s: Found.\n", tocEntryName);
|
fprintf(stderr, "%s: Found.\n", tocEntryName);
|
||||||
#endif
|
#endif
|
||||||
if((start+1)<toc->count) {
|
if((number+1)<toc->count) {
|
||||||
*pLength=(int32_t)(toc->entry[start+1].dataOffset-toc->entry[start].dataOffset);
|
*pLength=(int32_t)(toc->entry[number+1].dataOffset-toc->entry[number].dataOffset);
|
||||||
} else {
|
} else {
|
||||||
*pLength=-1;
|
*pLength=-1;
|
||||||
|
}
|
||||||
|
return (const DataHeader *)&base[toc->entry[number].dataOffset];
|
||||||
}
|
}
|
||||||
return (const DataHeader *)&base[toc->entry[start].dataOffset];
|
|
||||||
} else {
|
|
||||||
#ifdef UDATA_DEBUG
|
|
||||||
fprintf(stderr, "%s: Not found.\n", tocEntryName);
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
#ifdef UDATA_DEBUG
|
||||||
|
fprintf(stderr, "%s: Not found.\n", tocEntryName);
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
#ifdef UDATA_DEBUG
|
#ifdef UDATA_DEBUG
|
||||||
fprintf(stderr, "returning header\n");
|
fprintf(stderr, "returning header\n");
|
||||||
|
@ -371,7 +371,7 @@ static void TinyString_append(TinyString *This, const char *what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newLen < This->fCapacity) {
|
if (newLen < This->fCapacity) {
|
||||||
uprv_strcat(This->s, what);
|
uprv_strcat(This->s+This->length, what);
|
||||||
This->length = newLen;
|
This->length = newLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,7 +392,7 @@ static void TinyString_appendn(TinyString *This, const char *what, int32_t n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newLen < This->fCapacity) {
|
if (newLen < This->fCapacity) {
|
||||||
uprv_strncat(This->s, what, n);
|
uprv_strncat(This->s+This->length, what, n);
|
||||||
This->length = newLen;
|
This->length = newLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1058,7 +1058,6 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||||||
{
|
{
|
||||||
UDataMemory *retVal = NULL;
|
UDataMemory *retVal = NULL;
|
||||||
|
|
||||||
UDataPathIterator iter;
|
|
||||||
const char *pathBuffer;
|
const char *pathBuffer;
|
||||||
|
|
||||||
TinyString tocEntryName; /* entry name in tree format. ex: 'icudt28b/coll/ar.res' */
|
TinyString tocEntryName; /* entry name in tree format. ex: 'icudt28b/coll/ar.res' */
|
||||||
@ -1254,100 +1253,103 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||||||
|
|
||||||
dataPath = u_getDataDirectory();
|
dataPath = u_getDataDirectory();
|
||||||
|
|
||||||
/* #1a look in ind. files: package\nam.typ ========================= */
|
/* Check to make sure that there is a dataPath to iterate over */
|
||||||
/* init path iterator for individual files */
|
if (dataPath && *dataPath) {
|
||||||
udata_pathiter_init(&iter, dataPath, pkgName.s, path, tocEntryPathSuffix, FALSE);
|
UDataPathIterator iter;
|
||||||
|
/* #1a look in ind. files: package\nam.typ ========================= */
|
||||||
while((pathBuffer = udata_pathiter_next(&iter, NULL)))
|
/* init path iterator for individual files */
|
||||||
{
|
udata_pathiter_init(&iter, dataPath, pkgName.s, path, tocEntryPathSuffix, FALSE);
|
||||||
#ifdef UDATA_DEBUG
|
|
||||||
fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer);
|
|
||||||
#endif
|
|
||||||
if( uprv_mapFile(&dataMemory, pathBuffer) ||
|
|
||||||
(inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename)))
|
|
||||||
{
|
|
||||||
pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode);
|
|
||||||
if (pEntryData != NULL) {
|
|
||||||
/* Data is good.
|
|
||||||
* Hand off ownership of the backing memory to the user's UDataMemory.
|
|
||||||
* and return it. */
|
|
||||||
pEntryData->mapAddr = dataMemory.mapAddr;
|
|
||||||
pEntryData->map = dataMemory.map;
|
|
||||||
|
|
||||||
#ifdef UDATA_DEBUG
|
|
||||||
fprintf(stderr, "** Mapped file: %s\n", pathBuffer);
|
|
||||||
#endif
|
|
||||||
udata_pathiter_dt(&iter);
|
|
||||||
retVal = pEntryData;
|
|
||||||
goto commonReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the data is not acceptable, or some error occured. Either way, unmap the memory */
|
|
||||||
udata_close(&dataMemory);
|
|
||||||
|
|
||||||
/* If we had a nasty error, bail out completely. */
|
|
||||||
if (U_FAILURE(*pErrorCode)) {
|
|
||||||
udata_pathiter_dt(&iter);
|
|
||||||
retVal = NULL;
|
|
||||||
goto commonReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise remember that we found data but didn't like it for some reason */
|
|
||||||
errorCode=U_INVALID_FORMAT_ERROR;
|
|
||||||
}
|
|
||||||
#ifdef UDATA_DEBUG
|
|
||||||
fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
udata_pathiter_dt(&iter);
|
|
||||||
|
|
||||||
/* #1b look in ind. files - with old naming (package_nam.typ not package\nam.typ) ==================== */
|
while((pathBuffer = udata_pathiter_next(&iter, NULL)))
|
||||||
/* init path iterator for individual files */
|
|
||||||
udata_pathiter_init(&iter, dataPath, "", path, oldIndFileName.s, FALSE);
|
|
||||||
|
|
||||||
while((pathBuffer = udata_pathiter_next(&iter, NULL)))
|
|
||||||
{
|
|
||||||
#ifdef UDATA_DEBUG
|
|
||||||
fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer);
|
|
||||||
#endif
|
|
||||||
if( uprv_mapFile(&dataMemory, pathBuffer) ||
|
|
||||||
(inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename)))
|
|
||||||
{
|
{
|
||||||
pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode);
|
|
||||||
if (pEntryData != NULL) {
|
|
||||||
/* Data is good.
|
|
||||||
* Hand off ownership of the backing memory to the user's UDataMemory.
|
|
||||||
* and return it. */
|
|
||||||
pEntryData->mapAddr = dataMemory.mapAddr;
|
|
||||||
pEntryData->map = dataMemory.map;
|
|
||||||
|
|
||||||
#ifdef UDATA_DEBUG
|
#ifdef UDATA_DEBUG
|
||||||
fprintf(stderr, "** Mapped file: %s\n", pathBuffer);
|
fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer);
|
||||||
#endif
|
#endif
|
||||||
udata_pathiter_dt(&iter);
|
if( uprv_mapFile(&dataMemory, pathBuffer) ||
|
||||||
retVal = pEntryData;
|
(inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename)))
|
||||||
goto commonReturn;
|
{
|
||||||
}
|
pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode);
|
||||||
|
if (pEntryData != NULL) {
|
||||||
/* the data is not acceptable, or some error occured. Either way, unmap the memory */
|
/* Data is good.
|
||||||
udata_close(&dataMemory);
|
* Hand off ownership of the backing memory to the user's UDataMemory.
|
||||||
|
* and return it. */
|
||||||
/* If we had a nasty error, bail out completely. */
|
pEntryData->mapAddr = dataMemory.mapAddr;
|
||||||
if (U_FAILURE(*pErrorCode)) {
|
pEntryData->map = dataMemory.map;
|
||||||
udata_pathiter_dt(&iter);
|
|
||||||
retVal = NULL;
|
|
||||||
goto commonReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise remember that we found data but didn't like it for some reason */
|
|
||||||
errorCode=U_INVALID_FORMAT_ERROR;
|
|
||||||
}
|
|
||||||
#ifdef UDATA_DEBUG
|
|
||||||
fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
udata_pathiter_dt(&iter);
|
|
||||||
|
|
||||||
|
#ifdef UDATA_DEBUG
|
||||||
|
fprintf(stderr, "** Mapped file: %s\n", pathBuffer);
|
||||||
|
#endif
|
||||||
|
udata_pathiter_dt(&iter);
|
||||||
|
retVal = pEntryData;
|
||||||
|
goto commonReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the data is not acceptable, or some error occured. Either way, unmap the memory */
|
||||||
|
udata_close(&dataMemory);
|
||||||
|
|
||||||
|
/* If we had a nasty error, bail out completely. */
|
||||||
|
if (U_FAILURE(*pErrorCode)) {
|
||||||
|
udata_pathiter_dt(&iter);
|
||||||
|
retVal = NULL;
|
||||||
|
goto commonReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise remember that we found data but didn't like it for some reason */
|
||||||
|
errorCode=U_INVALID_FORMAT_ERROR;
|
||||||
|
}
|
||||||
|
#ifdef UDATA_DEBUG
|
||||||
|
fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
udata_pathiter_dt(&iter);
|
||||||
|
|
||||||
|
/* #1b look in ind. files - with old naming (package_nam.typ not package\nam.typ) ==================== */
|
||||||
|
/* init path iterator for individual files */
|
||||||
|
udata_pathiter_init(&iter, dataPath, "", path, oldIndFileName.s, FALSE);
|
||||||
|
|
||||||
|
while((pathBuffer = udata_pathiter_next(&iter, NULL)))
|
||||||
|
{
|
||||||
|
#ifdef UDATA_DEBUG
|
||||||
|
fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer);
|
||||||
|
#endif
|
||||||
|
if( uprv_mapFile(&dataMemory, pathBuffer) ||
|
||||||
|
(inBasename!=pathBuffer && uprv_mapFile(&dataMemory, inBasename)))
|
||||||
|
{
|
||||||
|
pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode);
|
||||||
|
if (pEntryData != NULL) {
|
||||||
|
/* Data is good.
|
||||||
|
* Hand off ownership of the backing memory to the user's UDataMemory.
|
||||||
|
* and return it. */
|
||||||
|
pEntryData->mapAddr = dataMemory.mapAddr;
|
||||||
|
pEntryData->map = dataMemory.map;
|
||||||
|
|
||||||
|
#ifdef UDATA_DEBUG
|
||||||
|
fprintf(stderr, "** Mapped file: %s\n", pathBuffer);
|
||||||
|
#endif
|
||||||
|
udata_pathiter_dt(&iter);
|
||||||
|
retVal = pEntryData;
|
||||||
|
goto commonReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the data is not acceptable, or some error occured. Either way, unmap the memory */
|
||||||
|
udata_close(&dataMemory);
|
||||||
|
|
||||||
|
/* If we had a nasty error, bail out completely. */
|
||||||
|
if (U_FAILURE(*pErrorCode)) {
|
||||||
|
udata_pathiter_dt(&iter);
|
||||||
|
retVal = NULL;
|
||||||
|
goto commonReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise remember that we found data but didn't like it for some reason */
|
||||||
|
errorCode=U_INVALID_FORMAT_ERROR;
|
||||||
|
}
|
||||||
|
#ifdef UDATA_DEBUG
|
||||||
|
fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
udata_pathiter_dt(&iter);
|
||||||
|
}
|
||||||
|
|
||||||
/* #2 */
|
/* #2 */
|
||||||
|
|
||||||
@ -1372,17 +1374,17 @@ doOpenChoice(const char *path, const char *type, const char *name,
|
|||||||
fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName.s, pHeader, u_errorName(errorCode));
|
fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName.s, pHeader, u_errorName(errorCode));
|
||||||
#endif
|
#endif
|
||||||
if((pHeader == NULL) && !U_FAILURE(errorCode)) {
|
if((pHeader == NULL) && !U_FAILURE(errorCode)) {
|
||||||
pHeader=pCommonData->vFuncs->Lookup(pCommonData, oldIndFileName.s, /* oldIndFileName is preceded by a slash */
|
pHeader=pCommonData->vFuncs->Lookup(pCommonData, oldIndFileName.s, /* oldIndFileName is preceded by a slash */
|
||||||
&length, &errorCode);
|
&length, &errorCode);
|
||||||
#ifdef UDATA_DEBUG
|
#ifdef UDATA_DEBUG
|
||||||
fprintf(stderr, "[OLD name] %s: pHeader=%p - %s\n", oldIndFileName.s, pHeader, u_errorName(errorCode));
|
fprintf(stderr, "[OLD name] %s: pHeader=%p - %s\n", oldIndFileName.s, pHeader, u_errorName(errorCode));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pHeader!=NULL) {
|
if(pHeader!=NULL) {
|
||||||
pEntryData = checkDataItem(pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode);
|
pEntryData = checkDataItem(pHeader, isAcceptable, context, type, name, &errorCode, pErrorCode);
|
||||||
#ifdef UDATA_DEBUG
|
#ifdef UDATA_DEBUG
|
||||||
fprintf(stderr, "pEntryData=%p\n", pEntryData);
|
fprintf(stderr, "pEntryData=%p\n", pEntryData);
|
||||||
#endif
|
#endif
|
||||||
if (U_FAILURE(*pErrorCode)) {
|
if (U_FAILURE(*pErrorCode)) {
|
||||||
retVal = NULL;
|
retVal = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user