public override void Add(char[] word, int start) { if (word.Length == start) { End = true; return; } int c = (int)word[start]; if (_next == null) { _next = new BurstNavigable[TRIE_WIDTH]; } BurstNavigable target = _next[c]; if (target == null) { // always start with a bucket. target = new BurstCacheBucket(); _next[c] = target; } else if (target.ShouldBurst) // else OK because there's never any need to burst a brand new bucket { target = BurstThisBucket(target); _next[c] = target; } target.Add(word, start + 1); }
BurstTrieNode BurstThisBucket(BurstNavigable bucketIn) { BurstCacheBucket bucket = (BurstCacheBucket)bucketIn; BurstTrieNode node = new BurstTrieNode { _next = new BurstNavigable[TRIE_WIDTH], End = bucket.End }; // node.me = key; // debug only // TODO maybe make this a higher performance construct? foreach (ArraySegment <char> item in bucket) { if (item.Count == 1) // in this case the suffix is consumed by the new trie node + entry (empty destination bucket, maybe, or now creating and adding to) { if (node._next[(int)item.Array[item.Offset]] == null) { BurstCacheBucket emptyBucket = new BurstCacheBucket(); emptyBucket.End = true; node._next[(int)item.Array[item.Offset]] = emptyBucket; // only needed if it was not there, so maybe save this assignment continue; } else // already a bucket there, from previous iteration in this loop { BurstCacheBucket reusingBucket = (BurstCacheBucket)node._next[(int)item.Array[item.Offset]]; reusingBucket.End = true; continue; } } else // there is more suffix that's not consumed by the new trie node + entry, so create / fill bucket { BurstNavigable nav = node._next[(int)item.Array[item.Offset]]; if (nav == null) { BurstCacheBucket newBucket = new BurstCacheBucket(); char[] arr = item.Array; int offset = item.Offset; newBucket.Add(arr, offset + 1, item.Count - 1); node._next[(int)arr[offset]] = newBucket; } else { ((BurstCacheBucket)nav).Add(item.Array, item.Offset + 1, item.Count - 1); } } } return(node); }