Example #1
0
/* Insert an element into the hash table pH.  The key is pKey,nKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
** element is created.  A copy of the key is made if the copyKey
** flag is set.  NULL is returned.
**
** If another element already exists with the same key, then the
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance.  If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
SQLITE_PRIVATE void *sqlite3Fts3HashInsert(
    Fts3Hash *pH,        /* The hash table to insert into */
    const void *pKey,    /* The key */
    int nKey,            /* Number of bytes in the key */
    void *data           /* The data */
) {
    int hraw;                 /* Raw hash value of the key */
    int h;                    /* the hash of the key modulo hash table size */
    Fts3HashElem *elem;       /* Used to loop thru the element list */
    Fts3HashElem *new_elem;   /* New element added to the pH */
    int (*xHash)(const void*,int);  /* The hash function */

    assert( pH!=0 );
    xHash = ftsHashFunction(pH->keyClass);
    assert( xHash!=0 );
    hraw = (*xHash)(pKey, nKey);
    assert( (pH->htsize & (pH->htsize-1))==0 );
    h = hraw & (pH->htsize-1);
    elem = fts3FindElementByHash(pH,pKey,nKey,h);
    if( elem ) {
        void *old_data = elem->data;
        if( data==0 ) {
            fts3RemoveElementByHash(pH,elem,h);
        } else {
            elem->data = data;
        }
        return old_data;
    }
    if( data==0 ) return 0;
    if( (pH->htsize==0 && fts3Rehash(pH,8))
            || (pH->count>=pH->htsize && fts3Rehash(pH, pH->htsize*2))
      ) {
        pH->count = 0;
        return data;
    }
    assert( pH->htsize>0 );
    new_elem = (Fts3HashElem*)fts3HashMalloc( sizeof(Fts3HashElem) );
    if( new_elem==0 ) return data;
    if( pH->copyKey && pKey!=0 ) {
        new_elem->pKey = fts3HashMalloc( nKey );
        if( new_elem->pKey==0 ) {
            fts3HashFree(new_elem);
            return data;
        }
        memcpy((void*)new_elem->pKey, pKey, nKey);
    } else {
        new_elem->pKey = (void*)pKey;
    }
    new_elem->nKey = nKey;
    pH->count++;
    assert( pH->htsize>0 );
    assert( (pH->htsize & (pH->htsize-1))==0 );
    h = hraw & (pH->htsize-1);
    fts3HashInsertElement(pH, &pH->ht[h], new_elem);
    new_elem->data = data;
    return 0;
}
Example #2
0
/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey.  Return the data for this element if it is
** found, or NULL if there is no match.
*/
void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){
  int h;                 /* A hash on key */
  Fts3HashElem *elem;    /* The element that matches key */
  int (*xHash)(const void*,int);  /* The hash function */

  if( pH==0 || pH->ht==0 ) return 0;
  xHash = ftsHashFunction(pH->keyClass);
  assert( xHash!=0 );
  h = (*xHash)(pKey,nKey);
  assert( (pH->htsize & (pH->htsize-1))==0 );
  elem = fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1));
  return elem ? elem->data : 0;
}
Example #3
0
SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(
    const Fts3Hash *pH,
    const void *pKey,
    int nKey
) {
    int h;                          /* A hash on key */
    int (*xHash)(const void*,int);  /* The hash function */

    if( pH==0 || pH->ht==0 ) return 0;
    xHash = ftsHashFunction(pH->keyClass);
    assert( xHash!=0 );
    h = (*xHash)(pKey,nKey);
    assert( (pH->htsize & (pH->htsize-1))==0 );
    return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1));
}
Example #4
0
/* Resize the hash table so that it cantains "new_size" buckets.
** "new_size" must be a power of 2.  The hash table might fail
** to resize if sqliteMalloc() fails.
**
** Return non-zero if a memory allocation error occurs.
*/
static int fts3Rehash(Fts3Hash *pH, int new_size) {
    struct _fts3ht *new_ht;          /* The new hash table */
    Fts3HashElem *elem, *next_elem;  /* For looping over existing elements */
    int (*xHash)(const void*,int);   /* The hash function */

    assert( (new_size & (new_size-1))==0 );
    new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) );
    if( new_ht==0 ) return 1;
    fts3HashFree(pH->ht);
    pH->ht = new_ht;
    pH->htsize = new_size;
    xHash = ftsHashFunction(pH->keyClass);
    for(elem=pH->first, pH->first=0; elem; elem = next_elem) {
        int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
        next_elem = elem->next;
        fts3HashInsertElement(pH, &new_ht[h], elem);
    }
    return 0;
}