aboutsummaryrefslogtreecommitdiff
path: root/ext/misc/spellfix.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/misc/spellfix.c')
-rw-r--r--ext/misc/spellfix.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c
index c0da6b339..cac1edcff 100644
--- a/ext/misc/spellfix.c
+++ b/ext/misc/spellfix.c
@@ -186,7 +186,7 @@ static const unsigned char className[] = ".ABCDHLRMY9 ?";
** Return NULL if memory allocation fails.
*/
static unsigned char *phoneticHash(const unsigned char *zIn, int nIn){
- unsigned char *zOut = sqlite3_malloc( nIn + 1 );
+ unsigned char *zOut = sqlite3_malloc64( nIn + 1 );
int i;
int nOut = 0;
char cPrev = 0x77;
@@ -365,8 +365,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
int *m; /* The cost matrix */
char *cx; /* Corresponding character values */
int *toFree = 0; /* Malloced space */
- int mStack[60+15]; /* Stack space to use if not too much is needed */
int nMatch = 0;
+ int mStack[60+15]; /* Stack space to use if not too much is needed */
/* Early out if either input is NULL */
if( zA==0 || zB==0 ) return -1;
@@ -413,7 +413,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
if( nB<(sizeof(mStack)*4)/(sizeof(mStack[0])*5) ){
m = mStack;
}else{
- m = toFree = sqlite3_malloc( (nB+1)*5*sizeof(m[0])/4 );
+ m = toFree = sqlite3_malloc64( (nB+1)*5*sizeof(m[0])/4 );
if( m==0 ) return -3;
}
cx = (char*)&m[nB+1];
@@ -687,7 +687,7 @@ static int editDist3ConfigLoad(
if( iCost<0 ) continue;
if( pLang==0 || iLang!=iLangPrev ){
EditDist3Lang *pNew;
- pNew = sqlite3_realloc(p->a, (p->nLang+1)*sizeof(p->a[0]));
+ pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0]));
if( pNew==0 ){ rc = SQLITE_NOMEM; break; }
p->a = pNew;
pLang = &p->a[p->nLang];
@@ -709,7 +709,7 @@ static int editDist3ConfigLoad(
EditDist3Cost *pCost;
int nExtra = nFrom + nTo - 4;
if( nExtra<0 ) nExtra = 0;
- pCost = sqlite3_malloc( sizeof(*pCost) + nExtra );
+ pCost = sqlite3_malloc64( sizeof(*pCost) + nExtra );
if( pCost==0 ){ rc = SQLITE_NOMEM; break; }
pCost->nFrom = nFrom;
pCost->nTo = nTo;
@@ -808,7 +808,7 @@ static EditDist3FromString *editDist3FromStringNew(
if( z==0 ) return 0;
if( n<0 ) n = (int)strlen(z);
- pStr = sqlite3_malloc( sizeof(*pStr) + sizeof(pStr->a[0])*n + n + 1 );
+ pStr = sqlite3_malloc64( sizeof(*pStr) + sizeof(pStr->a[0])*n + n + 1 );
if( pStr==0 ) return 0;
pStr->a = (EditDist3From*)&pStr[1];
memset(pStr->a, 0, sizeof(pStr->a[0])*n);
@@ -833,13 +833,13 @@ static EditDist3FromString *editDist3FromStringNew(
if( i+p->nFrom>n ) continue;
if( matchFrom(p, z+i, n-i)==0 ) continue;
if( p->nTo==0 ){
- apNew = sqlite3_realloc(pFrom->apDel,
+ apNew = sqlite3_realloc64(pFrom->apDel,
sizeof(*apNew)*(pFrom->nDel+1));
if( apNew==0 ) break;
pFrom->apDel = apNew;
apNew[pFrom->nDel++] = p;
}else{
- apNew = sqlite3_realloc(pFrom->apSubst,
+ apNew = sqlite3_realloc64(pFrom->apSubst,
sizeof(*apNew)*(pFrom->nSubst+1));
if( apNew==0 ) break;
pFrom->apSubst = apNew;
@@ -875,6 +875,17 @@ static void updateCost(
}
}
+/*
+** How much stack space (int bytes) to use for Wagner matrix in
+** editDist3Core(). If more space than this is required, the entire
+** matrix is taken from the heap. To reduce the load on the memory
+** allocator, make this value as large as practical for the
+** architecture in use.
+*/
+#ifndef SQLITE_SPELLFIX_STACKALLOC_SZ
+# define SQLITE_SPELLFIX_STACKALLOC_SZ (1024)
+#endif
+
/* Compute the edit distance between two strings.
**
** If an error occurs, return a negative number which is the error code.
@@ -899,15 +910,24 @@ static int editDist3Core(
EditDist3FromString f = *pFrom;
EditDist3To *a2;
unsigned int *m;
+ unsigned int *pToFree;
int szRow;
EditDist3Cost *p;
int res;
+ sqlite3_uint64 nByte;
+ unsigned int stackSpace[SQLITE_SPELLFIX_STACKALLOC_SZ/sizeof(unsigned int)];
/* allocate the Wagner matrix and the aTo[] array for the TO string */
n = (f.n+1)*(n2+1);
n = (n+1)&~1;
- m = sqlite3_malloc( n*sizeof(m[0]) + sizeof(a2[0])*n2 );
- if( m==0 ) return -1; /* Out of memory */
+ nByte = n*sizeof(m[0]) + sizeof(a2[0])*n2;
+ if( nByte<=sizeof(stackSpace) ){
+ m = stackSpace;
+ pToFree = 0;
+ }else{
+ m = pToFree = sqlite3_malloc64( nByte );
+ if( m==0 ) return -1; /* Out of memory */
+ }
a2 = (EditDist3To*)&m[n];
memset(a2, 0, sizeof(a2[0])*n2);
@@ -920,7 +940,7 @@ static int editDist3Core(
if( i2+p->nTo>n2 ) continue;
if( matchTo(p, z2+i2, n2-i2)==0 ) continue;
a2[i2].nIns++;
- apNew = sqlite3_realloc(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns);
+ apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns);
if( apNew==0 ){
res = -1; /* Out of memory */
goto editDist3Abort;
@@ -1029,7 +1049,7 @@ static int editDist3Core(
editDist3Abort:
for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns);
- sqlite3_free(m);
+ sqlite3_free(pToFree);
return res;
}
@@ -1098,7 +1118,7 @@ static void editDist3SqlFunc(
*/
static int editDist3Install(sqlite3 *db){
int rc;
- EditDist3Config *pConfig = sqlite3_malloc( sizeof(*pConfig) );
+ EditDist3Config *pConfig = sqlite3_malloc64( sizeof(*pConfig) );
if( pConfig==0 ) return SQLITE_NOMEM;
memset(pConfig, 0, sizeof(*pConfig));
rc = sqlite3_create_function_v2(db, "editdist3",
@@ -1587,7 +1607,7 @@ static const struct {
** should be freed by the caller.
*/
static unsigned char *transliterate(const unsigned char *zIn, int nIn){
- unsigned char *zOut = sqlite3_malloc( nIn*4 + 1 );
+ unsigned char *zOut = sqlite3_malloc64( nIn*4 + 1 );
int c, sz, nOut;
if( zOut==0 ) return 0;
nOut = 0;
@@ -1910,7 +1930,7 @@ static int spellfix1Init(
int i;
nDbName = (int)strlen(zDbName);
- pNew = sqlite3_malloc( sizeof(*pNew) + nDbName + 1);
+ pNew = sqlite3_malloc64( sizeof(*pNew) + nDbName + 1);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -2024,7 +2044,7 @@ static void spellfix1ResetCursor(spellfix1_cursor *pCur){
static void spellfix1ResizeCursor(spellfix1_cursor *pCur, int N){
struct spellfix1_row *aNew;
assert( N>=pCur->nRow );
- aNew = sqlite3_realloc(pCur->a, sizeof(pCur->a[0])*N);
+ aNew = sqlite3_realloc64(pCur->a, sizeof(pCur->a[0])*N);
if( aNew==0 && N>0 ){
spellfix1ResetCursor(pCur);
sqlite3_free(pCur->a);
@@ -2183,7 +2203,7 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
static int spellfix1Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
spellfix1_vtab *p = (spellfix1_vtab*)pVTab;
spellfix1_cursor *pCur;
- pCur = sqlite3_malloc( sizeof(*pCur) );
+ pCur = sqlite3_malloc64( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->pVTab = p;
@@ -2397,7 +2417,7 @@ static int spellfix1FilterForMatch(
/* Load the cost table if we have not already done so */
if( p->zCostTable!=0 && p->pConfig3==0 ){
- p->pConfig3 = sqlite3_malloc( sizeof(p->pConfig3[0]) );
+ p->pConfig3 = sqlite3_malloc64( sizeof(p->pConfig3[0]) );
if( p->pConfig3==0 ) return SQLITE_NOMEM;
memset(p->pConfig3, 0, sizeof(p->pConfig3[0]));
rc = editDist3ConfigLoad(p->pConfig3, p->db, p->zCostTable);