Changed the key length estimation function to create an actualy key if possible then cache the result to be

used in the key creation function,
bug 121281, r=ftang, sr=sfraser.
This commit is contained in:
nhotta%netscape.com 2002-02-12 22:17:19 +00:00
Родитель 12b3340b2a
Коммит 4495f7de53
2 изменённых файлов: 49 добавлений и 7 удалений

Просмотреть файл

@ -175,9 +175,36 @@ NS_IMETHODIMP nsCollationMacUC::GetSortKeyLen(
{ {
NS_ENSURE_ARG_POINTER(outLen); NS_ENSURE_ARG_POINTER(outLen);
// According to the document, the length of the key should typically be // If possible, a length is estimated by actually creating a key (and cache the result).
// If the string is too big then return the length by the formula.
PRUint32 stringLen = stringIn.Length();
// Set the default value for an output length.
// According to the documentation, the length of the key should typically be
// at least 5 * textLength // at least 5 * textLength
*outLen = (1 + stringIn.Length()) * 5 * sizeof(UCCollationValue); *outLen = (1 + stringIn.Length()) * 5 * sizeof(UCCollationValue);
if (stringLen > kCacheSize)
{
mCachedKeyLen = 0; // indicate key is not cached
return NS_OK;
}
nsresult res = EnsureCollator(strength);
NS_ENSURE_SUCCESS(res, res);
ItemCount actual;
memcpy((void *) mCachedString, (void *) PromiseFlatString(stringIn).get(),
stringLen * sizeof(UniChar));
OSErr err = ::UCGetCollationKey(mCollator, (const UniChar *) mCachedString,
(ItemCount) stringLen,
kCacheSize,
&actual, (UCCollationValue *) mCachedKey);
if (err == noErr)
*outLen = mCachedKeyLen = actual * sizeof(UCCollationValue);
else
mCachedKeyLen = 0;
return NS_OK; return NS_OK;
} }
@ -196,13 +223,21 @@ NS_IMETHODIMP nsCollationMacUC::CreateRawSortKey(
NS_ENSURE_SUCCESS(res, res); NS_ENSURE_SUCCESS(res, res);
OSStatus err; OSStatus err;
// this api is bad, we should pass in the length of key somewhere
// call GetSortKeyLen to get it instead.
PRUint32 keyLength;
res = GetSortKeyLen(strength, stringIn, &keyLength);
NS_ENSURE_SUCCESS(res, res);
// If we already get a key at the estimation then just copy the cached data.
if (mCachedKeyLen &&
!memcmp((void *) mCachedString,
(void *) (const UniChar*) PromiseFlatString(stringIn).get(), mCachedKeyLen))
{
memcpy((void *) key, (void *) mCachedKey, mCachedKeyLen);
*outLen = mCachedKeyLen;
return NS_OK;
}
// If not cached then call the API.
PRUint32 keyLength = (1 + stringIn.Length()) * 5 * sizeof(UCCollationValue);
ItemCount actual; ItemCount actual;
err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(), err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(),
(UniCharCount) stringIn.Length(), (UniCharCount) stringIn.Length(),
(ItemCount) (keyLength / sizeof(UCCollationValue)), (ItemCount) (keyLength / sizeof(UCCollationValue)),

Просмотреть файл

@ -45,6 +45,10 @@
#include <MacLocales.h> #include <MacLocales.h>
#include <UnicodeUtilities.h> #include <UnicodeUtilities.h>
// Maximum number of characters for a buffer to remember
// the generated collation key.
const PRUint32 kCacheSize = 80;
class nsCollationMacUC : public nsICollation { class nsCollationMacUC : public nsICollation {
public: public:
@ -85,6 +89,9 @@ private:
LocaleRef mLocale; LocaleRef mLocale;
nsCollationStrength mLastStrength; nsCollationStrength mLastStrength;
CollatorRef mCollator; CollatorRef mCollator;
UCCollationValue mCachedKey[kCacheSize * 5];
PRUint32 mCachedKeyLen; // byte length of key
UniChar mCachedString[kCacheSize];
}; };
#endif /* nsCollationMacUC_h__ */ #endif /* nsCollationMacUC_h__ */