加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
trieTree.cpp 18.21 KB
一键复制 编辑 原始数据 按行查看 历史
liwei 提交于 2018-11-18 20:11 . supoort alter table,rename table
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
/*
* trieTree.cpp
*
* Created on: 2018年11月5日
* Author: liwei
*/
#include "trieTree.h"
#include <string.h>
#include <assert.h>
#define TT_VALUE_MASK 0x8000000000000000UL
#define TT_NODE_LOW_MASK 0x07
#define TT_NODE_LOW_LEN 3
#define GET_NODE_LOW_OFFSET(v) ((v)&TT_NODE_LOW_MASK)
#define TT_NODE_MID_MASK 0x38
#define TT_NODE_MID_LEN 3
#define GET_NODE_MID_OFFSET(v) (((v)&TT_NODE_MID_MASK)>>(TT_NODE_LOW_LEN))
#define TT_NODE_HIGH_MASK 0xC0
#define TT_NODE_HIGH_LEN 2
#define GET_NODE_HIGH_OFFSET(v) (((v)&TT_NODE_HIGH_MASK)>>(TT_NODE_LOW_LEN+TT_NODE_MID_LEN))
void * trieTree::node::get(uint8_t c)
{
uint8_t off = GET_NODE_HIGH_OFFSET(c);
void ** next;
if ((next = static_cast<void**>(child[off])) != NULL)
{
off = GET_NODE_MID_OFFSET(c);
if ((next = static_cast<void**>(next[off])) != NULL)
return next[GET_NODE_LOW_OFFSET(c)];
}
return NULL;
}
bool trieTree::node::put(uint8_t c, void *value)
{
void ** mid, **low;
bool newMid = false;
bool newLow = false;
if (child == NULL)
{
void ** tmp = (void**) malloc(sizeof(void*) * (1 << TT_NODE_HIGH_LEN));
memset(tmp, 0, sizeof(void*) * (1 << TT_NODE_HIGH_LEN));
__asm__ __volatile__("mfence" ::: "memory");
child = tmp;
}
uint8_t _h = GET_NODE_HIGH_OFFSET(c);
if ((mid = static_cast<void**>(child[_h])) == NULL)
{
mid = (void**) malloc(sizeof(void*) * (1 << TT_NODE_MID_LEN));
memset(mid, 0, sizeof(void*) * (1 << TT_NODE_MID_LEN));
newMid = true;
}
uint8_t _m = GET_NODE_MID_OFFSET(c);
if ((low = static_cast<void**>(mid[_m])) == NULL)
{
low = (void**) malloc(sizeof(void*) * (1 << TT_NODE_LOW_LEN));
memset(low, 0, sizeof(void*) * (1 << TT_NODE_LOW_LEN));
newLow = true;
}
uint8_t _l = GET_NODE_LOW_OFFSET(c);
if (low[_l] == NULL)
{
low[_l] = value;
if (newLow)
{
__asm__ __volatile__("mfence" ::: "memory");
mid[_m] = low;
}
if (newMid)
{
__asm__ __volatile__("mfence" ::: "memory");
child[_h] = mid;
}
return true;
}
else
{
if (((uint64_t)low[_l] & TT_VALUE_MASK) && !((uint64_t)value & TT_VALUE_MASK))
{
static_cast<node*>(value)->put(0, low[_l]);
low[_l] = value;
if (newLow)
{
__asm__ __volatile__("mfence" ::: "memory");
mid[_m] = low;
}
if (newMid)
{
__asm__ __volatile__("mfence" ::: "memory");
child[_h] = mid;
}
return true;
}
else
return false;
}
}
trieTree::node::node(uint8_t _c) :
c(_c), num(0), child(NULL)
{
child = (void**)malloc(sizeof(void*)*(1 << TT_NODE_HIGH_LEN));
memset(child,0,sizeof(void*)*(1 << TT_NODE_HIGH_LEN));
}
trieTree::node::~node()
{
void ** mid, **low;
if (child != NULL)
{
for (uint8_t h = 0; h < (1 << TT_NODE_HIGH_LEN); h++)
{
if ((mid = static_cast<void**>(child[h])) != NULL)
{
for (uint8_t m = 0; m < (1 << TT_NODE_MID_LEN); m++)
{
if ((low = static_cast<void**>(mid[m])) != NULL)
free(low);
}
free(mid);
}
}
free(child);
child = NULL;
}
}
trieTree::node::iterator::iterator()
{
clear();
}
trieTree::node::iterator::iterator(const trieTree::node::iterator &iter) :
m_node(iter.m_node), h(iter.h), m_mid(iter.m_mid), m(iter.m), m_low(
iter.m_low), l(iter.l)
{
}
trieTree::node::iterator &trieTree::node::iterator::operator =(
const trieTree::node::iterator &iter)
{
m_node = iter.m_node;
h = iter.h;
m_mid = iter.m_mid;
m = iter.m;
m_low = iter.m_low;
l = iter.l;
return *this;
}
bool trieTree::node::iterator::valid()
{
return m_node && m_node->child && m_mid && m_low;
}
void trieTree::node::iterator::clear()
{
m_node = NULL;
h = 0;
m_mid = NULL;
m = 0;
m_low = NULL;
l = 0;
}
void * trieTree::node::iterator::value()
{
if (valid())
return m_low[l];
else
return NULL;
}
const trieTree::node * trieTree::node::iterator::getNode()
{
return m_node;
}
uint8_t trieTree::node::iterator::key()
{
return h * (1 << (TT_NODE_MID_LEN + TT_NODE_LOW_LEN))
+ m * (1 << TT_NODE_LOW_LEN) + l;
}
bool trieTree::node::iterator::next()
{
if (!valid())
return false;
l++;
for (; h < (1 << TT_NODE_HIGH_LEN); h++)
{
if ((m_mid = static_cast<void**>(m_node->child[h])) != NULL)
{
for (; m < (1 << TT_NODE_MID_LEN); m++)
{
if ((m_low = static_cast<void**>(m_mid[m])) != NULL)
{
for (; l < (1 << TT_NODE_LOW_LEN); l++)
{
if (m_low[l] != NULL)
return true;
}
l = 0;
}
}
l = m = 0;
}
}
return false;
}
trieTree::node::iterator trieTree::node::begin()
{
trieTree::node::iterator iter;
iter.m_node = this;
for (; iter.h < (1 << TT_NODE_HIGH_LEN); iter.h++)
{
if ((iter.m_mid = static_cast<void**>(child[iter.h])) != NULL)
{
for (; iter.m < (1 << TT_NODE_MID_LEN); iter.m++)
{
if ((iter.m_low = static_cast<void**>(iter.m_mid[iter.m]))
!= NULL)
{
for (; iter.l < (1 << TT_NODE_LOW_LEN); iter.l++)
{
if (iter.m_low[iter.l] != NULL)
return iter;
}
iter.l = 0;
}
}
iter.l = iter.m = 0;
}
}
iter.clear();
return iter;
}
trieTree::iterator::iterator()
{
m_stack.parent = NULL;
m_top = NULL;
memset(keyStack, 0, sizeof(keyStack));
keyStackTop = 0;
}
trieTree::iterator::iterator(const iterator & iter)
{
m_stack.nodeIter = iter.m_stack.nodeIter;
m_stack.parent = NULL;
m_top = NULL;
memcpy(keyStack, iter.keyStack, sizeof(keyStack));
keyStackTop = iter.keyStackTop;
stacks * copy = iter.m_top, *newStack = NULL;
while (copy != &iter.m_stack)
{
if (m_top == NULL)
{
m_top = new stacks;
m_top->nodeIter = iter.m_top->nodeIter;
newStack = m_top;
}
else
{
newStack->parent = new stacks;
newStack->parent->nodeIter = copy->nodeIter;
newStack = newStack->parent;
}
copy = copy->parent;
}
if (newStack == NULL)
m_top = &m_stack;
else
newStack->parent = &m_stack;
}
trieTree::iterator &trieTree::iterator::operator =(
const trieTree::iterator &iter)
{
m_stack.nodeIter = iter.m_stack.nodeIter;
m_stack.parent = NULL;
m_top = NULL;
stacks * copy = iter.m_top, *newStack = NULL;
keyStackTop = iter.keyStackTop;
memcpy(keyStack, iter.keyStack, sizeof(keyStack));
while (copy != &iter.m_stack)
{
if (m_top == NULL)
{
m_top = new stacks;
m_top->nodeIter = iter.m_top->nodeIter;
newStack = m_top;
}
else
{
newStack->parent = new stacks;
newStack->parent->nodeIter = copy->nodeIter;
newStack = newStack->parent;
}
copy = copy->parent;
}
if (newStack == NULL)
m_top = &m_stack;
else
newStack->parent = &m_stack;
return *this;
}
trieTree::iterator::~iterator()
{
clear();
}
void trieTree::iterator::clear()
{
if (m_top != NULL)
{
while (m_top != &m_stack)
{
stacks * p = m_top->parent;
delete m_top;
m_top = p;
}
m_top = NULL;
}
m_stack.nodeIter.clear();
memset(keyStack, 0, sizeof(keyStack));
keyStackTop = 0;
}
bool trieTree::iterator::valid()
{
return (m_top != NULL && m_top->nodeIter.valid()
&& ((uint64_t)m_top->nodeIter.value() & TT_VALUE_MASK));
}
void * trieTree::iterator::value()
{
if (!valid())
return NULL;
return (void*)((uint64_t)m_top->nodeIter.value() & (~TT_VALUE_MASK));
}
const unsigned char *trieTree::iterator::key() //todo
{
if (!valid())
return NULL;
return keyStack;
}
bool trieTree::iterator::next()
{
bool back = false;
while (true)
{
bool firstOfNode = m_top->nodeIter.key()=='\0';
if (m_top->nodeIter.next())
{
void * v = m_top->nodeIter.value();
if ((uint64_t)v & TT_VALUE_MASK)
{
if(!firstOfNode)
keyStack[keyStackTop-1] = m_top->nodeIter.key();
else
keyStack[keyStackTop++] = m_top->nodeIter.key();
return true;
}
else
{
if(back)
{
keyStack[--keyStackTop] = '\0';
back=false;
}
stacks * tmp = new stacks;
tmp->nodeIter = static_cast<node*>(v)->begin();
if (!tmp->nodeIter.valid()) //empty node
{
//abort();
delete tmp;
continue;
}
tmp->parent = m_top;
if(m_top->nodeIter.key()!='\0')
keyStack[keyStackTop++] = m_top->nodeIter.key();
m_top = tmp;
if ((uint64_t)m_top->nodeIter.value() & TT_VALUE_MASK)
return true;
}
}
else
{
stacks * parent = m_top->parent;
if (parent == NULL)
return false;
delete m_top;
m_top = parent;
keyStack[--keyStackTop] = '\0';
back = true;
}
}
}
trieTree::iterator trieTree::begin()
{
trieTree::iterator iter;
iter.m_stack.nodeIter = m_root.begin();
if (!iter.m_stack.nodeIter.valid())
{
iter.clear();
return iter;
}
iter.m_stack.parent = NULL;
iter.m_top = &iter.m_stack;
while (!((uint64_t)iter.m_top->nodeIter.value() & TT_VALUE_MASK))
{
iterator::stacks * tmp = new iterator::stacks;
tmp->nodeIter =
static_cast<node*>(iter.m_top->nodeIter.value())->begin();
if (!tmp->nodeIter.valid()) //empty node
{
//abort();
delete tmp;
if (!iter.next())
iter.clear();
return iter;
}
iter.keyStack[iter.keyStackTop++] = iter.m_top->nodeIter.key();
tmp->parent = iter.m_top;
iter.m_top = tmp;
if ((uint64_t)iter.m_top->nodeIter.value() & TT_VALUE_MASK)
return iter;
}
return iter;
}
trieTree::trieTree(int (*valueDestroyFunc)(void* value)) :
m_root(0), m_nodeCount(0), m_valueCount(0), m_valueDestroyFunc(
valueDestroyFunc)
{
}
trieTree::~trieTree()
{
clear();
}
void trieTree::clear()
{
iterator iter = begin();
if (iter.valid())
{
void * v = iter.value();
if (m_valueDestroyFunc)
m_valueDestroyFunc(v);
while (true)
{
if (iter.m_top->nodeIter.next())
{
v = iter.m_top->nodeIter.value();
if ((uint64_t)v & TT_VALUE_MASK)
{
if (m_valueDestroyFunc)
m_valueDestroyFunc((void*)((uint64_t)v & (~TT_VALUE_MASK)));
continue;
}
iterator::stacks * tmp = new iterator::stacks;
tmp->nodeIter = static_cast<node*>(v)->begin();
if (!tmp->nodeIter.valid()) //empty node
{
//abort();
delete tmp;
continue;
}
tmp->parent = iter.m_top;
iter.m_top = tmp;
if ((uint64_t)iter.m_top->nodeIter.value() & TT_VALUE_MASK)
{
if (m_valueDestroyFunc)
m_valueDestroyFunc(
(void*)((uint64_t)iter.m_top->nodeIter.value() &(~TT_VALUE_MASK)));
continue;
}
}
else
{
iterator::stacks * parent = iter.m_top->parent;
if (parent == NULL)
break;
delete iter.m_top->nodeIter.getNode();
delete iter.m_top;
iter.m_top = parent;
}
}
}
m_nodeCount = 0;
m_valueCount = 0;
}
int trieTree::insertNCase(const unsigned char * str,void *value)
{
node * n = &m_root;
void * v;
uint16_t level = 0;
uint8_t c;
node * topNewNode = NULL, *topNewNodeParent = NULL;
uint8_t topNewNodeOff = 0;
uint16_t newNodes = 0;
SEARCH:
c = str[level];
if(c>='A'&&c<='Z')
c += 'a'-'A';
if (str[level + 1] != '\0')
{
if ((v = n->get(c)) == NULL)
{
node * tmp = new node(c);
newNodes++;
if (topNewNode == NULL)
{
topNewNode = tmp;
topNewNodeParent = n;
topNewNodeOff = c;
}
else
n->put(c, tmp);
n = tmp;
}
else
{
if ((uint64_t)v & TT_VALUE_MASK)
{
node * tmp = new node(c);
newNodes++;
if (topNewNode == NULL)
{
topNewNode = tmp;
topNewNodeParent = n;
topNewNodeOff = c;
}
else
n->put(c, tmp);
n = tmp;
}
else
n = static_cast<node*>(v);
}
level++;
goto SEARCH;
}
else
{
if ((v = n->get(c)) == NULL)
{
n->put(c, (void*)((uint64_t)value | TT_VALUE_MASK));
}
else
{
if ((uint64_t)v & TT_VALUE_MASK)
return -1;
static_cast<node*>(v)->put(0, (void*)((uint64_t)value | TT_VALUE_MASK));
}
if (topNewNode != NULL)
{
__asm__ __volatile__("mfence" ::: "memory");
topNewNodeParent->put(topNewNodeOff, topNewNode); //add all new node to tree at last
}
m_nodeCount += newNodes;
m_valueCount++;
return 0;
}
}
int trieTree::insert(const unsigned char * str, void *value)
{
node * n = &m_root;
void * v;
uint16_t level = 0;
uint8_t c;
node * topNewNode = NULL, *topNewNodeParent = NULL;
uint8_t topNewNodeOff = 0;
uint16_t newNodes = 0;
SEARCH: c = str[level];
if (str[level + 1] != '\0')
{
if ((v = n->get(c)) == NULL)
{
node * tmp = new node(c);
newNodes++;
if (topNewNode == NULL)
{
topNewNode = tmp;
topNewNodeParent = n;
topNewNodeOff = c;
}
else
n->put(c, tmp);
n = tmp;
}
else
{
if ((uint64_t)v & TT_VALUE_MASK)
{
node * tmp = new node(c);
newNodes++;
if (topNewNode == NULL)
{
topNewNode = tmp;
topNewNodeParent = n;
topNewNodeOff = c;
}
else
n->put(c, tmp);
n = tmp;
}
else
n = static_cast<node*>(v);
}
level++;
goto SEARCH;
}
else
{
if ((v = n->get(c)) == NULL)
{
n->put(c, (void*)((uint64_t)value | TT_VALUE_MASK));
}
else
{
if ((uint64_t)v & TT_VALUE_MASK)
return -1;
static_cast<node*>(v)->put(0, (void*)((uint64_t)value | TT_VALUE_MASK));
}
if (topNewNode != NULL)
{
__asm__ __volatile__("mfence" ::: "memory");
topNewNodeParent->put(topNewNodeOff, topNewNode); //add all new node to tree at last
}
m_nodeCount += newNodes;
m_valueCount++;
return 0;
}
}
void * trieTree::findNCase(const unsigned char * str,uint32_t size)
{
node * n = &m_root;
void * v;
uint16_t level = 0;
uint8_t c;
SEARCH:
c = str[level];
if(c>='A'&&c<='Z')
c += 'a'-'A';
if (str[level + 1] != '\0'&&level<size-1)
{
if ((v = n->get(c)) == NULL)
return NULL;
if ((uint64_t)v & TT_VALUE_MASK)
return NULL;
n = static_cast<node*>(v);
level++;
goto SEARCH;
}
else
{
if ((v = n->get(c)) == NULL)
return NULL;
if ((uint64_t)v & TT_VALUE_MASK)
return (void*)((uint64_t)v & (~TT_VALUE_MASK));
else
{
v = static_cast<node*>(v)->get(0);
if(v==NULL)
return NULL;
if(!((uint64_t)v&TT_VALUE_MASK))
abort();
return (void*)((uint64_t)v&(~TT_VALUE_MASK));
}
}
}
void * trieTree::find(const unsigned char * str,uint32_t size)
{
node * n = &m_root;
void * v;
uint16_t level = 0;
uint8_t c;
SEARCH:
c = str[level];
if (str[level + 1] != '\0'&&level<size-1)
{
if ((v = n->get(c)) == NULL)
return NULL;
if ((uint64_t)v & TT_VALUE_MASK)
return NULL;
n = static_cast<node*>(v);
level++;
goto SEARCH;
}
else
{
if ((v = n->get(c)) == NULL)
return NULL;
if ((uint64_t)v & TT_VALUE_MASK)
return (void*)((uint64_t)v & (~TT_VALUE_MASK));
else
{
v = static_cast<node*>(v)->get(0);
if(v==NULL)
return NULL;
if(!((uint64_t)v&TT_VALUE_MASK))
abort();
return (void*)((uint64_t)v&(~TT_VALUE_MASK));
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化