ICU-4084 Improve doOpenChoice performance.

X-SVN-Rev: 16444
This commit is contained in:
George Rhoten 2004-10-11 21:21:55 +00:00
parent 4fbf096779
commit cf3b69cbf1
2 changed files with 123 additions and 116 deletions

View File

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

View File

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