Add FindOrSavePosition interface for suffix tree
authorteodor <teodor>
Fri, 11 Jul 2008 10:15:12 +0000 (10:15 +0000)
committerteodor <teodor>
Fri, 11 Jul 2008 10:15:12 +0000 (10:15 +0000)
sfxstr.c
sfxstr.h

index 0803345..337831c 100644 (file)
--- a/sfxstr.c
+++ b/sfxstr.c
@@ -144,21 +144,44 @@ SFSInit_c(SFSTree *info, char **in) {
 
 void*
 SFSFindData(SFSTree *info, char *word, int len) {
+       SFSDataIO       in;
+
+       in.key = word;
+       in.keylen = len;
+
+       return SFSFindDataOrSave(info, &in, NULL);
+}
+
+void*
+SFSFindDataOrSave(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*)word;
+       u_int8_t *ptr =(u_int8_t*)in->key;
+
+       if ( position ) {
+               position->nodeptr = NULL;
+               position->node = NULL;
+               position->level = 0;
+       }
+
+       while( node && !ISEND(ptr, in->key, in->keylen) ) {
+               if ( position ) {
+                       position->nodeptr = pnode;
+                       position->node = node;
+                       position->level =  ((char*)ptr) - in->key;
+               }
 
-       while( node && !ISEND(ptr, word, len) ) {
                if ( node->isskip ) {
-               
-                       if ( len>0 &&  len - (((char*)ptr) - word) > 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, word, len) && node->isword) {
+                               if ( ISEND(ptr, in->key, in->keylen) && node->isword) {
                                        return (void*) ( ((char*)(node->data)) + ((node->haschild) ? sizeof(SFSNode*) : 0) );
                                } else if ( node->haschild ) {
                                        node = getSkipChildPointer(info, node);
+                                       pnode = (SFSNode**)( (char*)(node->data) );
                                } else {
                                        return NULL;
                                }
@@ -171,10 +194,11 @@ SFSFindData(SFSTree *info, char *word, int len) {
                                StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
                                if ( StopMiddle->val == *ptr ) {
                                        ptr++;
-                                       if ( ISEND(ptr, word, len) && StopMiddle->isword ) {
+                                       if ( ISEND(ptr, in->key, in->keylen) && StopMiddle->isword ) {
                                                return (void*)( ((char*)node) + node->dataptr + info->datasize * StopMiddle->data );
                                        } else if ( StopMiddle->haschild ) {
                                                node = getChildPointer(info, StopMiddle);
+                                               pnode = (SFSNode**)(((char*)StopMiddle) + StopMiddle->child);
                                        } else {
                                                return NULL;
                                        }
@@ -192,6 +216,18 @@ SFSFindData(SFSTree *info, char *word, int len) {
        return NULL;
 }
 
+void
+SFSAddSaved(SFSTree *info, SFSDataIO *in, SFSTreePosition *position) {
+       CHECK_MEMORY(info);
+
+       if ( !(position->nodeptr && position->node) ) {
+               SFSAdd(info, in);
+               return;
+       }
+
+       *(position->nodeptr) = addRecord(info, position->node, in, position->level);
+}
+
 static void
 freeFSFNode(SFSTree *info, SFSNode *node, void (*freefunc)(void*)) {
        u_int32_t i;
index 22f8410..c49ac24 100644 (file)
--- a/sfxstr.h
+++ b/sfxstr.h
@@ -185,6 +185,15 @@ void SFSAdd(SFSTree *info, SFSDataIO *in);
  */
 void* SFSFindData(SFSTree *info, char *word, int len /* optional */ );
 
+typedef struct SFSTreePosition {
+       SFSNode         **nodeptr;
+       SFSNode          *node;
+       int                       level;
+} SFSTreePosition;
+
+void* SFSFindDataOrSave(SFSTree *info, SFSDataIO *in, SFSTreePosition *position);
+void  SFSAddSaved(SFSTree *info, SFSDataIO *in, SFSTreePosition *position);
+
 /*
  * éÎÉÃÉÁÌÉÚÁÃÉÑ ÉÔÅÒÁÔÏÒÁ × ÎÁÞÁÌÏ ÄÅÒÅ×Á 
  */