-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preparing for new persistent bst types
- Loading branch information
Showing
6 changed files
with
205 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package tree | ||
|
||
import ( | ||
"github.com/200sc/go-compgeo/printutil" | ||
"github.com/200sc/go-compgeo/search" | ||
) | ||
|
||
// FullPersistentBST is an implementation of a persistent | ||
// binary search tree using full copies, with each | ||
// instant represented by a separate BST. | ||
type FullPersistentBST struct { | ||
instant float64 | ||
index int | ||
// Implicitly sorted | ||
instants []BSTInstant | ||
} | ||
|
||
// BSTInstant is a single BST within a Persistent BST. | ||
type BSTInstant struct { | ||
*BST | ||
instant float64 | ||
} | ||
|
||
// ThisInstant returns the subtree at the most recent | ||
// instant set | ||
func (pbst *FullPersistentBST) ThisInstant() search.Dynamic { | ||
return pbst.instants[pbst.index] | ||
} | ||
|
||
// AtInstant returns the subtree of pbst at the given instant | ||
func (pbst *FullPersistentBST) AtInstant(ins float64) search.Dynamic { | ||
// binary search | ||
bot := 0 | ||
top := len(pbst.instants) - 1 | ||
var mid int | ||
for { | ||
if top <= bot { | ||
// round down | ||
if pbst.instants[bot].instant > ins { | ||
bot-- | ||
} | ||
return pbst.instants[bot] | ||
} | ||
mid = (bot + top) / 2 | ||
v := pbst.instants[mid].instant | ||
if v == ins { | ||
return pbst.instants[mid] | ||
} else if v < ins { | ||
bot = mid + 1 | ||
} else { | ||
top = mid - 1 | ||
} | ||
} | ||
} | ||
|
||
// ToStaticPersistent returns a static peristent version | ||
// of the pbst | ||
func (pbst *FullPersistentBST) ToStaticPersistent() search.StaticPersistent { | ||
// Todo | ||
return nil | ||
} | ||
|
||
// MinInstant returns the minimum instant ever set on pbst. | ||
func (pbst *FullPersistentBST) MinInstant() float64 { | ||
return pbst.instants[0].instant | ||
} | ||
|
||
// MaxInstant returns the maximum instant ever set on pbst. | ||
func (pbst *FullPersistentBST) MaxInstant() float64 { | ||
return pbst.instants[len(pbst.instants)-1].instant | ||
} | ||
|
||
// SetInstant increments the pbst to the given instant. | ||
func (pbst *FullPersistentBST) SetInstant(ins float64) { | ||
if ins < pbst.instant { | ||
panic("Decreasing instants is not yet supported") | ||
} else if ins == pbst.instant { | ||
return | ||
} | ||
bsti := BSTInstant{} | ||
bsti.BST = pbst.instants[len(pbst.instants)-1].copy() | ||
bsti.instant = ins | ||
pbst.instants = append(pbst.instants, bsti) | ||
pbst.instant = ins | ||
pbst.index++ | ||
} | ||
|
||
// Insert peforms Insert on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) Insert(n search.Node) error { | ||
return pbst.AtInstant(pbst.instant).Insert(n) | ||
} | ||
|
||
// Delete performs Delete on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) Delete(n search.Node) error { | ||
return pbst.AtInstant(pbst.instant).Delete(n) | ||
} | ||
|
||
// ToStatic performs ToStatic on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) ToStatic() search.Static { | ||
return pbst.AtInstant(pbst.instant).ToStatic() | ||
} | ||
|
||
// Size performs Size on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) Size() int { | ||
return pbst.AtInstant(pbst.instant).Size() | ||
} | ||
|
||
// InOrderTraverse performs InOrderTraverse on the current | ||
// set instant's search tree. | ||
func (pbst *FullPersistentBST) InOrderTraverse() []search.Node { | ||
return pbst.AtInstant(pbst.instant).InOrderTraverse() | ||
} | ||
|
||
// Search performs Search on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) Search(f interface{}) (bool, interface{}) { | ||
return pbst.AtInstant(pbst.instant).Search(f) | ||
} | ||
|
||
// SearchDown performs SearchDown on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) SearchDown(f interface{}, d int) (search.Comparable, interface{}) { | ||
return pbst.AtInstant(pbst.instant).SearchDown(f, d) | ||
} | ||
|
||
// SearchUp performs SearchUp on the current set instant's search tree. | ||
func (pbst *FullPersistentBST) SearchUp(f interface{}, u int) (search.Comparable, interface{}) { | ||
return pbst.AtInstant(pbst.instant).SearchUp(f, u) | ||
} | ||
|
||
// String returns a string representation of pbst. | ||
func (pbst *FullPersistentBST) String() string { | ||
s := "" | ||
for _, ins := range pbst.instants { | ||
s += printutil.Stringf64(ins.instant) + ":\n" | ||
s += ins.BST.String() | ||
} | ||
return s | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,64 @@ | ||
package tree | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
var ( | ||
instantInputs1 = [][]testNode{ | ||
{{1, 1}}, | ||
{{2, 1}}, | ||
{{3, 1}}, | ||
{{4, 1}}, | ||
{{5, 1}}, | ||
{{6, 1}}, | ||
{{7, 1}}, | ||
{{8, 1}}, | ||
{{9, 1}}, | ||
{{10, 1}}, | ||
} | ||
) | ||
|
||
func TestPBSTDefinedInput1(t *testing.T) { | ||
tree := New(RedBlack).ToPersistent() | ||
for i, ls := range instantInputs1 { | ||
tree.SetInstant(float64(i)) | ||
for _, v := range ls { | ||
err := tree.Insert(v) | ||
assert.Nil(t, err) | ||
} | ||
} | ||
for i := range instantInputs1 { | ||
t2 := tree.AtInstant(float64(i)) | ||
for j, ls2 := range instantInputs1 { | ||
if j > i { | ||
break | ||
} | ||
for _, v := range ls2 { | ||
found, _ := t2.Search(v.key) | ||
assert.True(t, found) | ||
} | ||
} | ||
} | ||
for i, ls := range instantInputs1 { | ||
tree.SetInstant(float64(len(instantInputs1) + i)) | ||
for _, v := range ls { | ||
err := tree.Delete(v) | ||
assert.Nil(t, err) | ||
} | ||
} | ||
for i := range instantInputs1 { | ||
t2 := tree.AtInstant(float64(len(instantInputs1) + i)) | ||
for j, ls2 := range instantInputs1 { | ||
if j > i { | ||
break | ||
} | ||
for _, v := range ls2 { | ||
found, _ := t2.Search(v.key) | ||
assert.False(t, found) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters