add .gitignore
[tedtools.git] / sfxstr.c
index c107e60..d65bf7c 100644 (file)
--- a/sfxstr.c
+++ b/sfxstr.c
@@ -149,20 +149,28 @@ SFSFindData(SFSTree *info, char *word, int len) {
        in.key = word;
        in.keylen = len;
 
-       return SFSFindDataOrSave(info, &in, NULL);
+       return SFSFindDataFromSavedOrSave(info, &in, NULL);
 }
 
 void*
 SFSFindDataOrSave(SFSTree *info, SFSDataIO *in, SFSTreePosition *position) {
+       if ( position )
+               memset(position, 0, sizeof(SFSTreePosition));
+
+       return SFSFindDataFromSavedOrSave(info, in, position); 
+}
+
+void*
+SFSFindDataFromSavedOrSave(SFSTree *info, SFSDataIO *in, SFSTreePosition *position) {
        SFSNode *node = info->node;
        SFSNode **pnode = &(info->node);
        SFSNodeData *StopLow, *StopHigh, *StopMiddle;
        u_int8_t *ptr =(u_int8_t*)in->key;
 
-       if ( position ) {
-               position->nodeptr = NULL;
-               position->node = NULL;
-               position->level = 0;
+       if ( position && position->nodeptr && position->node && in->keylen > position->level ) {
+               node = position->node;
+               pnode = position->nodeptr;
+               ptr += position->level;
        }
 
        while( node && !ISEND(ptr, in->key, in->keylen) ) {
@@ -173,15 +181,17 @@ SFSFindDataOrSave(SFSTree *info, SFSDataIO *in, SFSTreePosition *position) {
                }
 
                if ( node->isskip ) {
-                       if ( in->keylen>0 &&  in->keylen - (((char*)ptr) - in->key) > node->nchar )
+                       if ( in->keylen>0 &&  in->keylen - (((char*)ptr) - in->key) < node->nchar )
                                return NULL;
                        else if ( STRNCMP(ptr, ((char*)node)+node->dataptr, node->nchar) ) {
                                ptr+=node->nchar;
-                               if ( ISEND(ptr, in->key, in->keylen) && node->isword) {
-                                       return (void*) ( ((char*)(node->data)) + ((node->haschild) ? sizeof(SFSNode*) : 0) );
+                               if ( ISEND(ptr, in->key, in->keylen) ) {
+                                       if (node->isword)
+                                               return (void*) ( ((char*)(node->data)) + ((node->haschild) ? sizeof(SFSNode*) : 0) );
+                                       return NULL;
                                } else if ( node->haschild ) {
-                                       node = getSkipChildPointer(info, node);
                                        pnode = (SFSNode**)( (char*)(node->data) );
+                                       node = getSkipChildPointer(info, node);
                                } else {
                                        return NULL;
                                }
@@ -194,11 +204,13 @@ SFSFindDataOrSave(SFSTree *info, SFSDataIO *in, SFSTreePosition *position) {
                                StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
                                if ( StopMiddle->val == *ptr ) {
                                        ptr++;
-                                       if ( ISEND(ptr, in->key, in->keylen) && StopMiddle->isword ) {
-                                               return (void*)( ((char*)node) + node->dataptr + info->datasize * StopMiddle->data );
+                                       if ( ISEND(ptr, in->key, in->keylen) ) {
+                                               if ( StopMiddle->isword )
+                                                       return (void*)( ((char*)node) + node->dataptr + info->datasize * StopMiddle->data );
+                                               return NULL;
                                        } else if ( StopMiddle->haschild ) {
-                                               node = getChildPointer(info, StopMiddle);
                                                pnode = (SFSNode**)(((char*)StopMiddle) + StopMiddle->child);
+                                               node = getChildPointer(info, StopMiddle);
                                        } else {
                                                return NULL;
                                        }
@@ -220,7 +232,7 @@ void
 SFSAddSaved(SFSTree *info, SFSDataIO *in, SFSTreePosition *position) {
        CHECK_MEMORY(info);
 
-       if ( !(position->nodeptr && position->node) ) {
+       if ( !(position && position->nodeptr && position->node) ) {
                SFSAdd(info, in);
                return;
        }
@@ -626,11 +638,11 @@ addRecord(SFSTree *info, SFSNode* node, SFSDataIO *in, int level) {
                        else 
                                node = splitSkipNode(info, node, in, level); 
                } else {
-                       StopLow = node->data;   
+               StopLow = node->data;   
                        StopHigh = StopLow + node->nchar;
                        while (StopLow < StopHigh) {
                                StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
-                               if ( StopMiddle->val == *ptr ) {
+                       if ( StopMiddle->val == *ptr ) {
                                        if ( *(ptr+1)=='\0' ) {
                                                if ( StopMiddle->isword ) {
                                                        /* already exists */
@@ -791,8 +803,13 @@ SFSIterate(SFSTree *info, SFSDataIO *out) {
                return 1;
        }
 
-       if ( s == NULL || s->node == NULL)
+       if ( s == NULL )
                return 0;
+       if ( s->node == NULL ) {
+               info->stack = s->next;
+               tfree(s);
+               return SFSIterate(info, out);
+       }
                                                         
        while ( s->level + s->node->nchar + 1 >= info->tlen ) {
                info->tlen *= 2;
@@ -1109,8 +1126,9 @@ SFSWriteDump(SFSTree *info, char *filename, void *extradata, u_int32_t extrasize
 
                wp.info = info;
                wp.offset = 0;
-               
-               writeNode(&wp, fd, info->node, extrasize);
+       
+               if ( info->node )
+                       writeNode(&wp, fd, info->node, extrasize);
        }
        
        flock(fd, LOCK_UN);