示例#1
0
/* a is the new (conflicting node)
 * b is the node that needs to be split
 * d is the depth
 *
 * both a and b must be accepting nodes.
 */
func (b *TSTNode) split(a *TSTNode, d int) (t *TSTNode, err error) {
	if !a.accepting {
		return nil, errors.TSTError("`a` must be an accepting node")
	} else if !b.accepting {
		return nil, errors.TSTError("`b` must be an accepting node")
	}
	if d >= len(b.key) {
		return nil,
			errors.TSTError("depth of split exceeds key length of b")
	}
	t = NewTSTNode(b.ch)
	b = b.Copy()
	a = a.Copy()
	if d+1 < len(b.key) {
		b.ch = b.key[d+1]
	}
	a.ch = a.key[d]
	if a.ch < t.ch {
		t.m = b
		t.l = a
	} else if a.ch == t.ch {
		m, err := b.split(a, d+1)
		if err != nil {
			return nil, err
		}
		t.m = m
	} else if a.ch > t.ch {
		t.m = b
		t.r = a
	}
	if t.m == nil {
		panic("m is nil")
	}
	return t, nil
}
示例#2
0
func (n *TSTNode) insert(key ByteSlice, val interface{}, d int) (*TSTNode, error) {
	if d >= len(key) {
		return nil, errors.TSTError("depth exceeds key length")
	}
	if key[len(key)-1] != END {
		return nil, errors.TSTError("key must end in 0")
	}
	if n == nil {
		// if the node is nil we found teh spot, make a new node and return it
		return NewAcceptingTSTNode(key[d], key, val), nil
	} else if !n.Internal() {
		// if it is a leaf node we either have found the symbol or we need to
		// split the node
		if n.accepting && n.KeyEq(key) {
			n = n.Copy()
			n.value = val
			return n, nil
		} else {
			return n.split(NewAcceptingTSTNode(key[d], key, val), d)
		}
	} else {
		// it is an internal node
		ch := key[d]
		n = n.Copy()
		if ch < n.ch {
			l, err := n.l.insert(key, val, d)
			if err != nil {
				return nil, err
			}
			n.l = l
		} else if ch == n.ch {
			if d+1 == len(key) && ch == END {
				n.m = n.m.Copy()
				n.m.value = val
			} else {
				m, err := n.m.insert(key, val, d+1)
				if err != nil {
					return nil, err
				}
				n.m = m
			}
		} else if ch > n.ch {
			r, err := n.r.insert(key, val, d)
			if err != nil {
				return nil, err
			}
			n.r = r
		}
		return n, nil
	}
}