Merge pull request #17235 from taosdata/feat/TD-17777-V30
feat(shell): Supported the word completed by press Tab key for 3.0
This commit is contained in:
commit
1c106bfd1d
|
@ -24,7 +24,7 @@ void pressTabKey(SShellCmd* cmd);
|
||||||
// press othr key
|
// press othr key
|
||||||
void pressOtherKey(char c);
|
void pressOtherKey(char c);
|
||||||
|
|
||||||
// init shell auto funciton , shell start call once
|
// init shell auto funciton , shell start call once
|
||||||
bool shellAutoInit();
|
bool shellAutoInit();
|
||||||
|
|
||||||
// set conn
|
// set conn
|
||||||
|
|
|
@ -16,68 +16,65 @@
|
||||||
#ifndef __TRIE__
|
#ifndef __TRIE__
|
||||||
#define __TRIE__
|
#define __TRIE__
|
||||||
|
|
||||||
//
|
//
|
||||||
// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character
|
// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character
|
||||||
//
|
//
|
||||||
#define FIRST_ASCII 40 // first visiable char is '0'
|
#define FIRST_ASCII 40 // first visiable char is '0'
|
||||||
#define LAST_ASCII 122 // last visilbe char is 'z'
|
#define LAST_ASCII 122 // last visilbe char is 'z'
|
||||||
|
|
||||||
// capacity save char is 95
|
// capacity save char is 95
|
||||||
#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1)
|
#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1)
|
||||||
#define MAX_WORD_LEN 256 // max insert word length
|
#define MAX_WORD_LEN 256 // max insert word length
|
||||||
|
|
||||||
// define STire
|
// define STire
|
||||||
#define TIRE_TREE 0
|
#define TIRE_TREE 0
|
||||||
#define TIRE_LIST 1
|
#define TIRE_LIST 1
|
||||||
|
|
||||||
typedef struct STireNode {
|
typedef struct STireNode {
|
||||||
struct STireNode** d;
|
struct STireNode** d;
|
||||||
bool end; // record end flag
|
bool end; // record end flag
|
||||||
}STireNode;
|
} STireNode;
|
||||||
|
|
||||||
typedef struct StrName {
|
typedef struct StrName {
|
||||||
char * name;
|
char* name;
|
||||||
struct StrName * next;
|
struct StrName* next;
|
||||||
}StrName;
|
} StrName;
|
||||||
|
|
||||||
|
|
||||||
typedef struct STire {
|
typedef struct STire {
|
||||||
char type; // see define TIRE_
|
char type; // see define TIRE_
|
||||||
STireNode root;
|
STireNode root;
|
||||||
|
|
||||||
StrName * head;
|
StrName* head;
|
||||||
StrName * tail;
|
StrName* tail;
|
||||||
|
|
||||||
int count; // all count
|
int count; // all count
|
||||||
int ref;
|
int ref;
|
||||||
}STire;
|
} STire;
|
||||||
|
|
||||||
typedef struct SMatchNode {
|
typedef struct SMatchNode {
|
||||||
char* word;
|
char* word;
|
||||||
struct SMatchNode* next;
|
struct SMatchNode* next;
|
||||||
}SMatchNode;
|
} SMatchNode;
|
||||||
|
|
||||||
|
|
||||||
typedef struct SMatch {
|
typedef struct SMatch {
|
||||||
SMatchNode* head;
|
SMatchNode* head;
|
||||||
SMatchNode* tail; // append node to tail
|
SMatchNode* tail; // append node to tail
|
||||||
int count;
|
int count;
|
||||||
char pre[MAX_WORD_LEN];
|
char pre[MAX_WORD_LEN];
|
||||||
}SMatch;
|
} SMatch;
|
||||||
|
|
||||||
|
|
||||||
// ----------- interface -------------
|
// ----------- interface -------------
|
||||||
|
|
||||||
// create prefix search tree, return value call freeTire to free
|
// create prefix search tree, return value call freeTire to free
|
||||||
STire* createTire(char type);
|
STire* createTire(char type);
|
||||||
|
|
||||||
// destroy prefix search tree
|
// destroy prefix search tree
|
||||||
void freeTire(STire* tire);
|
void freeTire(STire* tire);
|
||||||
|
|
||||||
// add a new word
|
// add a new word
|
||||||
bool insertWord(STire* tire, char* word);
|
bool insertWord(STire* tire, char* word);
|
||||||
|
|
||||||
// add a new word
|
// add a new word
|
||||||
bool deleteWord(STire* tire, char* word);
|
bool deleteWord(STire* tire, char* word);
|
||||||
|
|
||||||
// match prefix words, if match is not NULL , put all item to match and return match
|
// match prefix words, if match is not NULL , put all item to match and return match
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,414 +22,405 @@
|
||||||
|
|
||||||
// create prefix search tree
|
// create prefix search tree
|
||||||
STire* createTire(char type) {
|
STire* createTire(char type) {
|
||||||
STire* tire = taosMemoryMalloc(sizeof(STire));
|
STire* tire = taosMemoryMalloc(sizeof(STire));
|
||||||
memset(tire, 0, sizeof(STire));
|
memset(tire, 0, sizeof(STire));
|
||||||
tire->ref = 1; // init is 1
|
tire->ref = 1; // init is 1
|
||||||
tire->type = type;
|
tire->type = type;
|
||||||
tire->root.d = (STireNode **)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode *));
|
tire->root.d = (STireNode**)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode*));
|
||||||
return tire;
|
return tire;
|
||||||
}
|
}
|
||||||
|
|
||||||
// free tire node
|
// free tire node
|
||||||
void freeTireNode(STireNode* node) {
|
void freeTireNode(STireNode* node) {
|
||||||
if (node == NULL)
|
if (node == NULL) return;
|
||||||
return ;
|
|
||||||
|
|
||||||
// nest free sub node on array d
|
|
||||||
if(node->d) {
|
|
||||||
for (int i = 0; i < CHAR_CNT; i++) {
|
|
||||||
freeTireNode(node->d[i]);
|
|
||||||
}
|
|
||||||
taosMemoryFree(node->d);
|
|
||||||
}
|
|
||||||
|
|
||||||
// free self
|
// nest free sub node on array d
|
||||||
taosMemoryFree(node);
|
if (node->d) {
|
||||||
|
for (int i = 0; i < CHAR_CNT; i++) {
|
||||||
|
freeTireNode(node->d[i]);
|
||||||
|
}
|
||||||
|
taosMemoryFree(node->d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// free self
|
||||||
|
taosMemoryFree(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy prefix search tree
|
// destroy prefix search tree
|
||||||
void freeTire(STire* tire) {
|
void freeTire(STire* tire) {
|
||||||
// free nodes
|
// free nodes
|
||||||
for (int i = 0; i < CHAR_CNT; i++) {
|
for (int i = 0; i < CHAR_CNT; i++) {
|
||||||
freeTireNode(tire->root.d[i]);
|
freeTireNode(tire->root.d[i]);
|
||||||
}
|
}
|
||||||
taosMemoryFree(tire->root.d);
|
taosMemoryFree(tire->root.d);
|
||||||
|
|
||||||
// free from list
|
// free from list
|
||||||
StrName * item = tire->head;
|
StrName* item = tire->head;
|
||||||
while (item) {
|
while (item) {
|
||||||
StrName * next = item->next;
|
StrName* next = item->next;
|
||||||
// free string
|
// free string
|
||||||
taosMemoryFree(item->name);
|
taosMemoryFree(item->name);
|
||||||
// free node
|
// free node
|
||||||
taosMemoryFree(item);
|
taosMemoryFree(item);
|
||||||
|
|
||||||
// move next
|
// move next
|
||||||
item = next;
|
item = next;
|
||||||
}
|
}
|
||||||
tire->head = tire->tail = NULL;
|
tire->head = tire->tail = NULL;
|
||||||
|
|
||||||
// free tire
|
// free tire
|
||||||
taosMemoryFree(tire);
|
taosMemoryFree(tire);
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a new word to list
|
// insert a new word to list
|
||||||
bool insertToList(STire* tire, char* word) {
|
bool insertToList(STire* tire, char* word) {
|
||||||
StrName * p = (StrName *)taosMemoryMalloc(sizeof(StrName));
|
StrName* p = (StrName*)taosMemoryMalloc(sizeof(StrName));
|
||||||
p->name = strdup(word);
|
p->name = strdup(word);
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
|
|
||||||
if(tire->head == NULL) {
|
|
||||||
tire->head = p;
|
|
||||||
tire->tail = p;
|
|
||||||
}else {
|
|
||||||
tire->tail->next = p;
|
|
||||||
tire->tail = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
if (tire->head == NULL) {
|
||||||
|
tire->head = p;
|
||||||
|
tire->tail = p;
|
||||||
|
} else {
|
||||||
|
tire->tail->next = p;
|
||||||
|
tire->tail = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a new word to tree
|
// insert a new word to tree
|
||||||
bool insertToTree(STire* tire, char* word, int len) {
|
bool insertToTree(STire* tire, char* word, int len) {
|
||||||
int m = 0;
|
int m = 0;
|
||||||
STireNode ** nodes = tire->root.d;
|
STireNode** nodes = tire->root.d;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
m = word[i] - FIRST_ASCII;
|
m = word[i] - FIRST_ASCII;
|
||||||
if (m < 0 || m > CHAR_CNT) {
|
if (m < 0 || m > CHAR_CNT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (nodes[m] == NULL) {
|
|
||||||
// no pointer
|
|
||||||
STireNode* p = (STireNode* )taosMemoryMalloc(sizeof(STireNode));
|
|
||||||
memset(p, 0, sizeof(STireNode));
|
|
||||||
nodes[m] = p;
|
|
||||||
if (i == len - 1) {
|
|
||||||
// is end
|
|
||||||
p->end = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodes[m]->d == NULL) {
|
|
||||||
// malloc d
|
|
||||||
nodes[m]->d = (STireNode **)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode *));
|
|
||||||
}
|
|
||||||
|
|
||||||
// move to next node
|
|
||||||
nodes = nodes[m]->d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add count
|
if (nodes[m] == NULL) {
|
||||||
tire->count += 1;
|
// no pointer
|
||||||
return true;
|
STireNode* p = (STireNode*)taosMemoryMalloc(sizeof(STireNode));
|
||||||
|
memset(p, 0, sizeof(STireNode));
|
||||||
|
nodes[m] = p;
|
||||||
|
if (i == len - 1) {
|
||||||
|
// is end
|
||||||
|
p->end = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes[m]->d == NULL) {
|
||||||
|
// malloc d
|
||||||
|
nodes[m]->d = (STireNode**)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode*));
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next node
|
||||||
|
nodes = nodes[m]->d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add count
|
||||||
|
tire->count += 1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a new word
|
// insert a new word
|
||||||
bool insertWord(STire* tire, char* word) {
|
bool insertWord(STire* tire, char* word) {
|
||||||
int len = strlen(word);
|
int len = strlen(word);
|
||||||
if (len >= MAX_WORD_LEN) {
|
if (len >= MAX_WORD_LEN) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tire->type) {
|
|
||||||
case TIRE_TREE:
|
|
||||||
return insertToTree(tire, word, len);
|
|
||||||
case TIRE_LIST:
|
|
||||||
return insertToList(tire, word);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tire->type) {
|
||||||
|
case TIRE_TREE:
|
||||||
|
return insertToTree(tire, word, len);
|
||||||
|
case TIRE_LIST:
|
||||||
|
return insertToList(tire, word);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete one word from list
|
// delete one word from list
|
||||||
bool deleteFromList(STire* tire, char* word) {
|
bool deleteFromList(STire* tire, char* word) {
|
||||||
StrName * item = tire->head;
|
StrName* item = tire->head;
|
||||||
while (item) {
|
while (item) {
|
||||||
if (strcmp(item->name, word) == 0) {
|
if (strcmp(item->name, word) == 0) {
|
||||||
// found, reset empty to delete
|
// found, reset empty to delete
|
||||||
item->name[0] = 0;
|
item->name[0] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
// move next
|
|
||||||
item = item->next;
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
// move next
|
||||||
|
item = item->next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete one word from tree
|
// delete one word from tree
|
||||||
bool deleteFromTree(STire* tire, char* word, int len) {
|
bool deleteFromTree(STire* tire, char* word, int len) {
|
||||||
int m = 0;
|
int m = 0;
|
||||||
bool del = false;
|
bool del = false;
|
||||||
|
|
||||||
STireNode** nodes = tire->root.d;
|
STireNode** nodes = tire->root.d;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
m = word[i] - FIRST_ASCII;
|
m = word[i] - FIRST_ASCII;
|
||||||
if (m < 0 || m >= CHAR_CNT) {
|
if (m < 0 || m >= CHAR_CNT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (nodes[m] == NULL) {
|
|
||||||
// no found
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// not null
|
|
||||||
if(i == len - 1) {
|
|
||||||
// this is last, only set end false , not free node
|
|
||||||
nodes[m]->end = false;
|
|
||||||
del = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nodes[m]->d == NULL)
|
|
||||||
break;
|
|
||||||
// move to next node
|
|
||||||
nodes = nodes[m]->d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduce count
|
if (nodes[m] == NULL) {
|
||||||
if (del) {
|
// no found
|
||||||
tire->count -= 1;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return del;
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert a new word
|
|
||||||
bool deleteWord(STire* tire, char* word) {
|
|
||||||
int len = strlen(word);
|
|
||||||
if (len >= MAX_WORD_LEN) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tire->type) {
|
|
||||||
case TIRE_TREE:
|
|
||||||
return deleteFromTree(tire, word, len);
|
|
||||||
case TIRE_LIST:
|
|
||||||
return deleteFromList(tire, word);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addWordToMatch(SMatch* match, char* word){
|
|
||||||
// malloc new
|
|
||||||
SMatchNode* node = (SMatchNode* )taosMemoryMalloc(sizeof(SMatchNode));
|
|
||||||
memset(node, 0, sizeof(SMatchNode));
|
|
||||||
node->word = strdup(word);
|
|
||||||
|
|
||||||
// append to match
|
|
||||||
if (match->head == NULL) {
|
|
||||||
match->head = match->tail = node;
|
|
||||||
} else {
|
} else {
|
||||||
match->tail->next = node;
|
// not null
|
||||||
match->tail = node;
|
if (i == len - 1) {
|
||||||
|
// this is last, only set end false , not free node
|
||||||
|
nodes[m]->end = false;
|
||||||
|
del = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
match->count += 1;
|
|
||||||
|
if (nodes[m]->d == NULL) break;
|
||||||
|
// move to next node
|
||||||
|
nodes = nodes[m]->d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reduce count
|
||||||
|
if (del) {
|
||||||
|
tire->count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return del;
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert a new word
|
||||||
|
bool deleteWord(STire* tire, char* word) {
|
||||||
|
int len = strlen(word);
|
||||||
|
if (len >= MAX_WORD_LEN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tire->type) {
|
||||||
|
case TIRE_TREE:
|
||||||
|
return deleteFromTree(tire, word, len);
|
||||||
|
case TIRE_LIST:
|
||||||
|
return deleteFromList(tire, word);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addWordToMatch(SMatch* match, char* word) {
|
||||||
|
// malloc new
|
||||||
|
SMatchNode* node = (SMatchNode*)taosMemoryMalloc(sizeof(SMatchNode));
|
||||||
|
memset(node, 0, sizeof(SMatchNode));
|
||||||
|
node->word = strdup(word);
|
||||||
|
|
||||||
|
// append to match
|
||||||
|
if (match->head == NULL) {
|
||||||
|
match->head = match->tail = node;
|
||||||
|
} else {
|
||||||
|
match->tail->next = node;
|
||||||
|
match->tail = node;
|
||||||
|
}
|
||||||
|
match->count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum all words from node
|
// enum all words from node
|
||||||
void enumAllWords(STireNode** nodes, char* prefix, SMatch* match) {
|
void enumAllWords(STireNode** nodes, char* prefix, SMatch* match) {
|
||||||
STireNode * c;
|
STireNode* c;
|
||||||
char word[MAX_WORD_LEN];
|
char word[MAX_WORD_LEN];
|
||||||
int len = strlen(prefix);
|
int len = strlen(prefix);
|
||||||
for (int i = 0; i < CHAR_CNT; i++) {
|
for (int i = 0; i < CHAR_CNT; i++) {
|
||||||
c = nodes[i];
|
c = nodes[i];
|
||||||
|
|
||||||
if (c == NULL) {
|
|
||||||
// chain end node
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// combine word string
|
|
||||||
memset(word, 0, sizeof(word));
|
|
||||||
strcpy(word, prefix);
|
|
||||||
word[len] = FIRST_ASCII + i; // append current char
|
|
||||||
|
|
||||||
// chain middle node
|
if (c == NULL) {
|
||||||
if (c->end) {
|
// chain end node
|
||||||
// have end flag
|
continue;
|
||||||
addWordToMatch(match, word);
|
} else {
|
||||||
}
|
// combine word string
|
||||||
// nested call next layer
|
memset(word, 0, sizeof(word));
|
||||||
if (c->d)
|
strcpy(word, prefix);
|
||||||
enumAllWords(c->d, word, match);
|
word[len] = FIRST_ASCII + i; // append current char
|
||||||
}
|
|
||||||
|
// chain middle node
|
||||||
|
if (c->end) {
|
||||||
|
// have end flag
|
||||||
|
addWordToMatch(match, word);
|
||||||
|
}
|
||||||
|
// nested call next layer
|
||||||
|
if (c->d) enumAllWords(c->d, word, match);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// match prefix from list
|
// match prefix from list
|
||||||
void matchPrefixFromList(STire* tire, char* prefix, SMatch* match) {
|
void matchPrefixFromList(STire* tire, char* prefix, SMatch* match) {
|
||||||
StrName * item = tire->head;
|
StrName* item = tire->head;
|
||||||
int len = strlen(prefix);
|
int len = strlen(prefix);
|
||||||
while (item) {
|
while (item) {
|
||||||
if ( strncmp(item->name, prefix, len) == 0) {
|
if (strncmp(item->name, prefix, len) == 0) {
|
||||||
// prefix matched
|
// prefix matched
|
||||||
addWordToMatch(match, item->name);
|
addWordToMatch(match, item->name);
|
||||||
}
|
|
||||||
|
|
||||||
// move next
|
|
||||||
item = item->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// move next
|
||||||
|
item = item->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// match prefix words, if match is not NULL , put all item to match and return match
|
// match prefix words, if match is not NULL , put all item to match and return match
|
||||||
void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) {
|
void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) {
|
||||||
SMatch* root = match;
|
SMatch* root = match;
|
||||||
int m = 0;
|
int m = 0;
|
||||||
STireNode* c = 0;
|
STireNode* c = 0;
|
||||||
int len = strlen(prefix);
|
int len = strlen(prefix);
|
||||||
if (len >= MAX_WORD_LEN) {
|
if (len >= MAX_WORD_LEN) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
STireNode** nodes = tire->root.d;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
m = prefix[i] - FIRST_ASCII;
|
||||||
|
if (m < 0 || m > CHAR_CNT) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
STireNode** nodes = tire->root.d;
|
// match
|
||||||
for (int i = 0; i < len; i++) {
|
c = nodes[m];
|
||||||
m = prefix[i] - FIRST_ASCII;
|
if (c == NULL) {
|
||||||
if (m < 0 || m > CHAR_CNT) {
|
// arrive end
|
||||||
return;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// match
|
|
||||||
c = nodes[m];
|
|
||||||
if (c == NULL) {
|
|
||||||
// arrive end
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// previous items already matched
|
|
||||||
if (i == len - 1) {
|
|
||||||
// malloc match if not pass by param match
|
|
||||||
if (root == NULL) {
|
|
||||||
root = (SMatch* )taosMemoryMalloc(sizeof(SMatch));
|
|
||||||
memset(root, 0, sizeof(SMatch));
|
|
||||||
strcpy(root->pre, prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefix is match to end char
|
|
||||||
if (c->d)
|
|
||||||
enumAllWords(c->d, prefix, root);
|
|
||||||
} else {
|
|
||||||
// move to next node continue match
|
|
||||||
if(c->d == NULL)
|
|
||||||
break;
|
|
||||||
nodes = c->d;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return
|
// previous items already matched
|
||||||
return ;
|
if (i == len - 1) {
|
||||||
|
// malloc match if not pass by param match
|
||||||
|
if (root == NULL) {
|
||||||
|
root = (SMatch*)taosMemoryMalloc(sizeof(SMatch));
|
||||||
|
memset(root, 0, sizeof(SMatch));
|
||||||
|
strcpy(root->pre, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prefix is match to end char
|
||||||
|
if (c->d) enumAllWords(c->d, prefix, root);
|
||||||
|
} else {
|
||||||
|
// move to next node continue match
|
||||||
|
if (c->d == NULL) break;
|
||||||
|
nodes = c->d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) {
|
SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) {
|
||||||
if(match == NULL) {
|
if (match == NULL) {
|
||||||
match = (SMatch* )taosMemoryMalloc(sizeof(SMatch));
|
match = (SMatch*)taosMemoryMalloc(sizeof(SMatch));
|
||||||
memset(match, 0, sizeof(SMatch));
|
memset(match, 0, sizeof(SMatch));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tire->type) {
|
switch (tire->type) {
|
||||||
case TIRE_TREE:
|
case TIRE_TREE:
|
||||||
matchPrefixFromTree(tire, prefix, match);
|
matchPrefixFromTree(tire, prefix, match);
|
||||||
case TIRE_LIST:
|
case TIRE_LIST:
|
||||||
matchPrefixFromList(tire, prefix, match);
|
matchPrefixFromList(tire, prefix, match);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return if need
|
// return if need
|
||||||
if (match->count == 0) {
|
if (match->count == 0) {
|
||||||
freeMatch(match);
|
freeMatch(match);
|
||||||
match = NULL;
|
match = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get all items from tires tree
|
// get all items from tires tree
|
||||||
void enumFromList(STire* tire, SMatch* match) {
|
void enumFromList(STire* tire, SMatch* match) {
|
||||||
StrName * item = tire->head;
|
StrName* item = tire->head;
|
||||||
while (item) {
|
while (item) {
|
||||||
if (item->name[0] != 0) {
|
if (item->name[0] != 0) {
|
||||||
// not delete
|
// not delete
|
||||||
addWordToMatch(match, item->name);
|
addWordToMatch(match, item->name);
|
||||||
}
|
|
||||||
|
|
||||||
// move next
|
|
||||||
item = item->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// move next
|
||||||
|
item = item->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all items from tires tree
|
// get all items from tires tree
|
||||||
void enumFromTree(STire* tire, SMatch* match) {
|
void enumFromTree(STire* tire, SMatch* match) {
|
||||||
char pre[2] ={0, 0};
|
char pre[2] = {0, 0};
|
||||||
STireNode* c;
|
STireNode* c;
|
||||||
|
|
||||||
// enum first layer
|
|
||||||
for (int i = 0; i < CHAR_CNT; i++) {
|
|
||||||
pre[0] = FIRST_ASCII + i;
|
|
||||||
|
|
||||||
// each node
|
|
||||||
c = tire->root.d[i];
|
|
||||||
if (c == NULL) {
|
|
||||||
// this branch no data
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this branch have data
|
// enum first layer
|
||||||
if(c->end)
|
for (int i = 0; i < CHAR_CNT; i++) {
|
||||||
addWordToMatch(match, pre);
|
pre[0] = FIRST_ASCII + i;
|
||||||
else
|
|
||||||
matchPrefix(tire, pre, match);
|
// each node
|
||||||
|
c = tire->root.d[i];
|
||||||
|
if (c == NULL) {
|
||||||
|
// this branch no data
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this branch have data
|
||||||
|
if (c->end)
|
||||||
|
addWordToMatch(match, pre);
|
||||||
|
else
|
||||||
|
matchPrefix(tire, pre, match);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all items from tires tree
|
// get all items from tires tree
|
||||||
SMatch* enumAll(STire* tire) {
|
SMatch* enumAll(STire* tire) {
|
||||||
SMatch* match = (SMatch* )taosMemoryMalloc(sizeof(SMatch));
|
SMatch* match = (SMatch*)taosMemoryMalloc(sizeof(SMatch));
|
||||||
memset(match, 0, sizeof(SMatch));
|
memset(match, 0, sizeof(SMatch));
|
||||||
|
|
||||||
switch (tire->type) {
|
switch (tire->type) {
|
||||||
case TIRE_TREE:
|
case TIRE_TREE:
|
||||||
enumFromTree(tire, match);
|
enumFromTree(tire, match);
|
||||||
case TIRE_LIST:
|
case TIRE_LIST:
|
||||||
enumFromList(tire, match);
|
enumFromList(tire, match);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return if need
|
// return if need
|
||||||
if (match->count == 0) {
|
if (match->count == 0) {
|
||||||
freeMatch(match);
|
freeMatch(match);
|
||||||
match = NULL;
|
match = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// free match result
|
// free match result
|
||||||
void freeMatchNode(SMatchNode* node) {
|
void freeMatchNode(SMatchNode* node) {
|
||||||
// first free next
|
// first free next
|
||||||
if (node->next)
|
if (node->next) freeMatchNode(node->next);
|
||||||
freeMatchNode(node->next);
|
|
||||||
|
|
||||||
// second free self
|
// second free self
|
||||||
if (node->word)
|
if (node->word) taosMemoryFree(node->word);
|
||||||
taosMemoryFree(node->word);
|
taosMemoryFree(node);
|
||||||
taosMemoryFree(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// free match result
|
// free match result
|
||||||
void freeMatch(SMatch* match) {
|
void freeMatch(SMatch* match) {
|
||||||
// first free next
|
// first free next
|
||||||
if (match->head) {
|
if (match->head) {
|
||||||
freeMatchNode(match->head);
|
freeMatchNode(match->head);
|
||||||
}
|
}
|
||||||
|
|
||||||
// second free self
|
// second free self
|
||||||
taosMemoryFree(match);
|
taosMemoryFree(match);
|
||||||
}
|
}
|
Loading…
Reference in New Issue