static inline void insert(TrieNode<CharT, BucketT>* root, unsigned char** strings, size_t n) { for (size_t i=0; i < n; ++i) { unsigned char* str = strings[i]; size_t depth = 0; CharT c = get_char<CharT>(str, 0); TrieNode<CharT, BucketT>* node = root; while (node->is_trie(c)) { assert(not is_end(c)); node = node->get_node(c); depth += sizeof(CharT); c = get_char<CharT>(str, depth); } BucketT* bucket = node->get_bucket(c); assert(bucket); bucket->push_back(str); if (is_end(c)) continue; if (bucket->size() > Threshold) { node->_buckets[c] = BurstImpl()(*bucket, depth+sizeof(CharT)); make_trie(node->_buckets[c]); delete bucket; } } }
static inline size_t handle_bucket(TSTNode<CharT>* node, unsigned char** strings, size_t pos, size_t depth) { static_assert(BucketNum < 3, "BucketNum < 3"); if (node->is_tst[BucketNum]) { pos = burst_traverse<BucketT>( static_cast<TSTNode<CharT>*>(node->buckets[BucketNum]), strings, pos, depth + (BucketNum==1)*sizeof(CharT)); } else if (node->buckets[BucketNum]) { BucketT* buck = static_cast<BucketT*>(node->buckets[BucketNum]); size_t bsize = buck->size(); std::copy(buck->begin(), buck->end(), strings+pos); delete buck; if (not is_middle_bucket(BucketNum)) { mkqsort(strings+pos, bsize, depth); } else if (not is_end(node->pivot)) { mkqsort(strings+pos, bsize, depth+sizeof(CharT)); } pos += bsize; } return pos; }
bool additem(ElemType elem, CountType count) { count=1; if(bs_->next_==NULL) { bs_->next_=new BucketT(count, bs_, NULL); end_=bs_->next_; } BucketT* bp=bs_->next_; ItemT* i=new ItemT(elem, bp, NULL, NULL); if(bp->c_ == count) { bp->insert(i); } else { BucketT* nbp = new BucketT(count, bs_, bs_->next_); bs_->next_ = nbp; nbp->next_->prev_=nbp; nbp->insert(i); } size_++; gps_[elem]=i; th_=bs_->next_->c_; return true; }
bool update(ElemType elem, CountType count) { ItemT* i = gps_[elem]; BucketT* bp = i->b_; count = bp->c_+1; if(bp->size_==1 && (!(bp->next_) || bp->next_->c_ > count)) { bp->c_++; th_ = bs_->next_->c_; return true; } bp->erase(i); if(!(bp->next_)) { bp->next_=new BucketT(count, bp, NULL); end_=bp->next_; } else if(bp->next_->c_ > count) { BucketT* tp=new BucketT(count, bp, bp->next_); bp->next_=tp; tp->next_->prev_=tp; } bp->next_->insert(i); if(bp->size_==0) { bp->prev_->next_=bp->next_; bp->next_->prev_=bp->prev_; bp->next_=bp->prev_=NULL; delete bp; } return true; }
static inline void burst_insert(TSTNode<CharT>* root, unsigned char** strings, size_t N) { for (size_t i=0; i < N; ++i) { unsigned char* str = strings[i]; size_t depth = 0; CharT c = get_char<CharT>(str, depth); TSTNode<CharT>* node = root; unsigned bucket = get_bucket(c, node->pivot); while (node->is_tst[bucket]) { if (is_middle_bucket(bucket)) { depth += sizeof(CharT); c = get_char<CharT>(str, depth); } node = static_cast<TSTNode<CharT>*>( node->buckets[bucket]); bucket = get_bucket(c, node->pivot); } BucketT* buck = static_cast<BucketT*>(node->buckets[bucket]); if (not buck) node->buckets[bucket] = buck = new BucketT; buck->push_back(str); if (is_middle_bucket(bucket) && is_end(node->pivot)) { continue; } if (buck->size() > sizeof(CharT)*Threshold and buck->size() == buck->capacity()) { if (is_middle_bucket(bucket)) { depth += sizeof(CharT); } CharT* oracle = static_cast<CharT*>( malloc(buck->size()*sizeof(CharT))); for (unsigned j=0; j < buck->size(); ++j) { oracle[j] = get_char<CharT>((*buck)[j], depth); } TSTNode<CharT>* new_node = BurstImpl()(*buck, oracle, depth); free(oracle); delete buck; node->buckets[bucket] = new_node; node->is_tst[bucket] = true; } } }
static inline void copy(const BucketT& bucket, OutputIterator dst) { std::copy(bucket.begin(), bucket.end(), dst); }