// deleteRecursive is used by the delete logic.  The recursion depth
// only goes as far as the number of dimensions, so this shouldn't be an
// issue.
func (rt *skipListRT) deleteRecursive(sl *skip.SkipList, dimension uint64,
	entry rangetree.Entry) rangetree.Entry {

	value := entry.ValueAtDimension(dimension)
	if isLastDimension(dimension, rt.dimensions) {
		entries := sl.Delete(skipEntry(value))
		if entries[0] == nil {
			return nil
		}

		rt.number--
		return entries[0].(*lastBundle).entry
	}

	db, ok := sl.Get(skipEntry(value))[0].(*dimensionalBundle)
	if !ok { // value was not found
		return nil
	}

	result := rt.deleteRecursive(db.sl, dimension+1, entry)
	if result == nil {
		return nil
	}

	if db.sl.Len() == 0 {
		sl.Delete(db)
	}

	return result
}
func (rt *skipListRT) insert(sl *skip.SkipList, dimension, insertDimension uint64,
	index, number int64, deleted, affected *rangetree.Entries) {

	var e common.Comparator
	lastDimension := isLastDimension(dimension, rt.dimensions)
	affectedDimension := dimension == insertDimension
	var iter skip.Iterator
	if dimension == insertDimension {
		iter = sl.Iter(skipEntry(index))
	} else {
		iter = sl.Iter(skipEntry(0))
	}

	var toDelete common.Comparators
	if number < 0 {
		toDelete = make(common.Comparators, 0, 100)
	}

	for iter.Next() {
		e = iter.Value()
		if !affectedDimension {
			rt.insert(e.(*dimensionalBundle).sl, dimension+1,
				insertDimension, index, number, deleted, affected,
			)
			continue
		}
		if needsDeletion(int64(e.(keyed).key()), index, number) {
			toDelete = append(toDelete, e)
			continue
		}

		if lastDimension {
			e.(*lastBundle).id += uint64(number)
			*affected = append(*affected, e.(*lastBundle).entry)
		} else {
			e.(*dimensionalBundle).id += uint64(number)
			rt.flatten(e.(*dimensionalBundle).sl, dimension+1, affected)
		}
	}

	if len(toDelete) > 0 {
		for _, e := range toDelete {
			if lastDimension {
				*deleted = append(*deleted, e.(*lastBundle).entry)
			} else {
				rt.flatten(e.(*dimensionalBundle).sl, dimension+1, deleted)
			}
		}

		sl.Delete(toDelete...)
	}
}