1
0
Fork 0
mirror of https://github.com/Luzifer/ansible-role-version.git synced 2024-12-22 18:41:22 +00:00

Update dependencies

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2018-03-19 18:16:10 +01:00
parent fe680c31db
commit 209b813c5b
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
2298 changed files with 1037783 additions and 285 deletions

179
Gopkg.lock generated
View file

@ -1,12 +1,55 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/emirpasic/gods"
packages = [
"containers",
"lists",
"lists/arraylist",
"trees",
"trees/binaryheap",
"utils"
]
revision = "f6c17b524822278a87e3b3bd809fec33b51f5b46"
version = "v1.9.0"
[[projects]] [[projects]]
name = "github.com/inconshreveable/mousetrap" name = "github.com/inconshreveable/mousetrap"
packages = ["."] packages = ["."]
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0" version = "v1.0"
[[projects]]
branch = "master"
name = "github.com/jbenet/go-context"
packages = ["io"]
revision = "d14ea06fba99483203c19d92cfcd13ebe73135f4"
[[projects]]
name = "github.com/kevinburke/ssh_config"
packages = ["."]
revision = "9fc7bb800b555d63157c65a904c86a2cc7b4e795"
version = "0.4"
[[projects]]
branch = "master"
name = "github.com/mitchellh/go-homedir"
packages = ["."]
revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
[[projects]]
name = "github.com/pelletier/go-buffruneio"
packages = ["."]
revision = "c37440a7cf42ac63b919c752ca73a85067e05992"
version = "v0.2.0"
[[projects]]
name = "github.com/sergi/go-diff"
packages = ["diffmatchpatch"]
revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
version = "v1.0.0"
[[projects]] [[projects]]
name = "github.com/spf13/cobra" name = "github.com/spf13/cobra"
packages = ["."] packages = ["."]
@ -20,14 +63,144 @@
version = "v1.0.0" version = "v1.0.0"
[[projects]] [[projects]]
branch = "v2" name = "github.com/src-d/gcfg"
packages = [
".",
"scanner",
"token",
"types"
]
revision = "f187355171c936ac84a82793659ebb4936bc1c23"
version = "v1.3.0"
[[projects]]
branch = "master"
name = "github.com/xanzy/ssh-agent"
packages = ["."]
revision = "ba9c9e33906f58169366275e3450db66139a31a9"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = [
"cast5",
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"internal/chacha20",
"openpgp",
"openpgp/armor",
"openpgp/elgamal",
"openpgp/errors",
"openpgp/packet",
"openpgp/s2k",
"poly1305",
"ssh",
"ssh/agent",
"ssh/knownhosts"
]
revision = "c3a3ad6d03f7a915c0f7e194b7152974bb73d287"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = ["context"]
revision = "92b859f39abd2d91a854c9f9c4621b2f5054a92d"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["windows"]
revision = "d8e400bc7db4870d786864138af681469693d18c"
[[projects]]
name = "golang.org/x/text"
packages = [
"internal/gen",
"internal/triegen",
"internal/ucd",
"transform",
"unicode/cldr",
"unicode/norm"
]
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
name = "gopkg.in/src-d/go-billy.v4"
packages = [
".",
"helper/chroot",
"helper/polyfill",
"memfs",
"osfs",
"util"
]
revision = "027dceab1aa836eb310d92c2eb2266e4dc9f4b81"
version = "v4.1.0"
[[projects]]
name = "gopkg.in/src-d/go-git.v4"
packages = [
".",
"config",
"internal/revision",
"plumbing",
"plumbing/cache",
"plumbing/filemode",
"plumbing/format/config",
"plumbing/format/diff",
"plumbing/format/gitignore",
"plumbing/format/idxfile",
"plumbing/format/index",
"plumbing/format/objfile",
"plumbing/format/packfile",
"plumbing/format/pktline",
"plumbing/object",
"plumbing/protocol/packp",
"plumbing/protocol/packp/capability",
"plumbing/protocol/packp/sideband",
"plumbing/revlist",
"plumbing/storer",
"plumbing/transport",
"plumbing/transport/client",
"plumbing/transport/file",
"plumbing/transport/git",
"plumbing/transport/http",
"plumbing/transport/internal/common",
"plumbing/transport/server",
"plumbing/transport/ssh",
"storage",
"storage/filesystem",
"storage/filesystem/internal/dotgit",
"storage/memory",
"utils/binary",
"utils/diff",
"utils/ioutil",
"utils/merkletrie",
"utils/merkletrie/filesystem",
"utils/merkletrie/index",
"utils/merkletrie/internal/frame",
"utils/merkletrie/noder"
]
revision = "1d28459504251497e0ce6132a0fadd5eb44ffd22"
version = "v4.2.0"
[[projects]]
name = "gopkg.in/warnings.v0"
packages = ["."]
revision = "ec4a0fea49c7b46c2aeb0b51aac55779c607e52b"
version = "v0.1.2"
[[projects]]
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
packages = ["."] packages = ["."]
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4" revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5"
version = "v2.1.1"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "7ff1f45772d06d809a7ce689131011edc8fbd443f3b3d5b819110f42ad9d5283" inputs-digest = "232dd462ee87625b6d06a386c00dff327b7e8f1033800dd1383ea2d9e2c94dd4"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

26
vendor/github.com/emirpasic/gods/.gitignore generated vendored Normal file
View file

@ -0,0 +1,26 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
.idea

10
vendor/github.com/emirpasic/gods/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,10 @@
language: go
go:
- 1.1
- 1.2
- 1.3
- 1.4
- 1.5
- 1.6
- 1.7
- tip

41
vendor/github.com/emirpasic/gods/LICENSE generated vendored Normal file
View file

@ -0,0 +1,41 @@
Copyright (c) 2015, Emir Pasic
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------------------
AVL Tree:
Copyright (c) 2017 Benjamin Scher Purcell <benjapurcell@gmail.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

1436
vendor/github.com/emirpasic/gods/README.md generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,35 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package containers provides core interfaces and functions for data structures.
//
// Container is the base interface for all data structures to implement.
//
// Iterators provide stateful iterators.
//
// Enumerable provides Ruby inspired (each, select, map, find, any?, etc.) container functions.
//
// Serialization provides serializers (marshalers) and deserializers (unmarshalers).
package containers
import "github.com/emirpasic/gods/utils"
// Container is base interface that all data structures implement.
type Container interface {
Empty() bool
Size() int
Clear()
Values() []interface{}
}
// GetSortedValues returns sorted container's elements with respect to the passed comparator.
// Does not effect the ordering of elements within the container.
func GetSortedValues(container Container, comparator utils.Comparator) []interface{} {
values := container.Values()
if len(values) < 2 {
return values
}
utils.Sort(values, comparator)
return values
}

View file

@ -0,0 +1,55 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// All data structures must implement the container structure
package containers
import (
"github.com/emirpasic/gods/utils"
"testing"
)
// For testing purposes
type ContainerTest struct {
values []interface{}
}
func (container ContainerTest) Empty() bool {
return len(container.values) == 0
}
func (container ContainerTest) Size() int {
return len(container.values)
}
func (container ContainerTest) Clear() {
container.values = []interface{}{}
}
func (container ContainerTest) Values() []interface{} {
return container.values
}
func TestGetSortedValuesInts(t *testing.T) {
container := ContainerTest{}
container.values = []interface{}{5, 1, 3, 2, 4}
values := GetSortedValues(container, utils.IntComparator)
for i := 1; i < container.Size(); i++ {
if values[i-1].(int) > values[i].(int) {
t.Errorf("Not sorted!")
}
}
}
func TestGetSortedValuesStrings(t *testing.T) {
container := ContainerTest{}
container.values = []interface{}{"g", "a", "d", "e", "f", "c", "b"}
values := GetSortedValues(container, utils.StringComparator)
for i := 1; i < container.Size(); i++ {
if values[i-1].(string) > values[i].(string) {
t.Errorf("Not sorted!")
}
}
}

View file

@ -0,0 +1,61 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package containers
// EnumerableWithIndex provides functions for ordered containers whose values can be fetched by an index.
type EnumerableWithIndex interface {
// Each calls the given function once for each element, passing that element's index and value.
Each(func(index int, value interface{}))
// Map invokes the given function once for each element and returns a
// container containing the values returned by the given function.
// TODO need help on how to enforce this in containers (don't want to type assert when chaining)
// Map(func(index int, value interface{}) interface{}) Container
// Select returns a new container containing all elements for which the given function returns a true value.
// TODO need help on how to enforce this in containers (don't want to type assert when chaining)
// Select(func(index int, value interface{}) bool) Container
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
Any(func(index int, value interface{}) bool) bool
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
All(func(index int, value interface{}) bool) bool
// Find passes each element of the container to the given function and returns
// the first (index,value) for which the function is true or -1,nil otherwise
// if no element matches the criteria.
Find(func(index int, value interface{}) bool) (int, interface{})
}
// EnumerableWithKey provides functions for ordered containers whose values whose elements are key/value pairs.
type EnumerableWithKey interface {
// Each calls the given function once for each element, passing that element's key and value.
Each(func(key interface{}, value interface{}))
// Map invokes the given function once for each element and returns a container
// containing the values returned by the given function as key/value pairs.
// TODO need help on how to enforce this in containers (don't want to type assert when chaining)
// Map(func(key interface{}, value interface{}) (interface{}, interface{})) Container
// Select returns a new container containing all elements for which the given function returns a true value.
// TODO need help on how to enforce this in containers (don't want to type assert when chaining)
// Select(func(key interface{}, value interface{}) bool) Container
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
Any(func(key interface{}, value interface{}) bool) bool
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
All(func(key interface{}, value interface{}) bool) bool
// Find passes each element of the container to the given function and returns
// the first (key,value) for which the function is true or nil,nil otherwise if no element
// matches the criteria.
Find(func(key interface{}, value interface{}) bool) (interface{}, interface{})
}

109
vendor/github.com/emirpasic/gods/containers/iterator.go generated vendored Normal file
View file

@ -0,0 +1,109 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package containers
// IteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
type IteratorWithIndex interface {
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
Next() bool
// Value returns the current element's value.
// Does not modify the state of the iterator.
Value() interface{}
// Index returns the current element's index.
// Does not modify the state of the iterator.
Index() int
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
Begin()
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
First() bool
}
// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
type IteratorWithKey interface {
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
Next() bool
// Value returns the current element's value.
// Does not modify the state of the iterator.
Value() interface{}
// Key returns the current element's key.
// Does not modify the state of the iterator.
Key() interface{}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
Begin()
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
First() bool
}
// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
//
// Essentially it is the same as IteratorWithIndex, but provides additional:
//
// Prev() function to enable traversal in reverse
//
// Last() function to move the iterator to the last element.
//
// End() function to move the iterator past the last element (one-past-the-end).
type ReverseIteratorWithIndex interface {
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
Prev() bool
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
End()
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
Last() bool
IteratorWithIndex
}
// ReverseIteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
//
// Essentially it is the same as IteratorWithKey, but provides additional:
//
// Prev() function to enable traversal in reverse
//
// Last() function to move the iterator to the last element.
type ReverseIteratorWithKey interface {
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
Prev() bool
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
End()
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
Last() bool
IteratorWithKey
}

View file

@ -0,0 +1,17 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package containers
// JSONSerializer provides JSON serialization
type JSONSerializer interface {
// ToJSON outputs the JSON representation of containers's elements.
ToJSON() ([]byte, error)
}
// JSONDeserializer provides JSON deserialization
type JSONDeserializer interface {
// FromJSON populates containers's elements from the input JSON representation.
FromJSON([]byte) error
}

31
vendor/github.com/emirpasic/gods/examples/arraylist.go generated vendored Normal file
View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/utils"
)
// ArrayListExample to demonstrate basic usage of ArrayList
func ArrayListExample() {
list := arraylist.New()
list.Add("a") // ["a"]
list.Add("c", "b") // ["a","c","b"]
list.Sort(utils.StringComparator) // ["a","b","c"]
_, _ = list.Get(0) // "a",true
_, _ = list.Get(100) // nil,false
_ = list.Contains("a", "b", "c") // true
_ = list.Contains("a", "b", "c", "d") // false
list.Swap(0, 1) // ["b","a",c"]
list.Remove(2) // ["b","a"]
list.Remove(1) // ["b"]
list.Remove(0) // []
list.Remove(0) // [] (ignored)
_ = list.Empty() // true
_ = list.Size() // 0
list.Add("a") // ["a"]
list.Clear() // []
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/stacks/arraystack"
// ArrayStackExample to demonstrate basic usage of ArrayStack
func ArrayStackExample() {
stack := arraystack.New() // empty
stack.Push(1) // 1
stack.Push(2) // 1, 2
stack.Values() // 2, 1 (LIFO order)
_, _ = stack.Peek() // 2,true
_, _ = stack.Pop() // 2, true
_, _ = stack.Pop() // 1, true
_, _ = stack.Pop() // nil, false (nothing to pop)
stack.Push(1) // 1
stack.Clear() // empty
stack.Empty() // true
stack.Size() // 0
}

50
vendor/github.com/emirpasic/gods/examples/avltree.go generated vendored Normal file
View file

@ -0,0 +1,50 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
avl "github.com/emirpasic/gods/trees/avltree"
)
// AVLTreeExample to demonstrate basic usage of AVLTree
func AVLTreeExample() {
tree := avl.NewWithIntComparator() // empty(keys are of type int)
tree.Put(1, "x") // 1->x
tree.Put(2, "b") // 1->x, 2->b (in order)
tree.Put(1, "a") // 1->a, 2->b (in order, replacement)
tree.Put(3, "c") // 1->a, 2->b, 3->c (in order)
tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order)
tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)
tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
//
// AVLTree
// │ ┌── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
_ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f"} (in order)
_ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order)
tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
//
// AVLTree
// │ ┌── 6
// │ ┌── 5
// └── 4
// └── 3
// └── 1
tree.Clear() // empty
tree.Empty() // true
tree.Size() // 0
}

View file

@ -0,0 +1,40 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"github.com/emirpasic/gods/trees/binaryheap"
"github.com/emirpasic/gods/utils"
)
// BinaryHeapExample to demonstrate basic usage of BinaryHeap
func BinaryHeapExample() {
// Min-heap
heap := binaryheap.NewWithIntComparator() // empty (min-heap)
heap.Push(2) // 2
heap.Push(3) // 2, 3
heap.Push(1) // 1, 3, 2
heap.Values() // 1, 3, 2
_, _ = heap.Peek() // 1,true
_, _ = heap.Pop() // 1, true
_, _ = heap.Pop() // 2, true
_, _ = heap.Pop() // 3, true
_, _ = heap.Pop() // nil, false (nothing to pop)
heap.Push(1) // 1
heap.Clear() // empty
heap.Empty() // true
heap.Size() // 0
// Max-heap
inverseIntComparator := func(a, b interface{}) int {
return -utils.IntComparator(a, b)
}
heap = binaryheap.NewWith(inverseIntComparator) // empty (min-heap)
heap.Push(2) // 2
heap.Push(3) // 3, 2
heap.Push(1) // 3, 2, 1
heap.Values() // 3, 2, 1
}

59
vendor/github.com/emirpasic/gods/examples/btree.go generated vendored Normal file
View file

@ -0,0 +1,59 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/trees/btree"
)
// BTreeExample to demonstrate basic usage of BTree
func BTreeExample() {
tree := btree.NewWithIntComparator(3) // empty (keys are of type int)
tree.Put(1, "x") // 1->x
tree.Put(2, "b") // 1->x, 2->b (in order)
tree.Put(1, "a") // 1->a, 2->b (in order, replacement)
tree.Put(3, "c") // 1->a, 2->b, 3->c (in order)
tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order)
tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)
tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)
tree.Put(7, "g") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order)
fmt.Println(tree)
// BTree
// 1
// 2
// 3
// 4
// 5
// 6
// 7
_ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f", "g"} (in order)
_ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order)
tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
// BTree
// 1
// 3
// 4
// 5
// 6
tree.Clear() // empty
tree.Empty() // true
tree.Size() // 0
// Other:
tree.Height() // gets the height of the tree
tree.Left() // gets the left-most (min) node
tree.LeftKey() // get the left-most (min) node's key
tree.LeftValue() // get the left-most (min) node's value
tree.Right() // get the right-most (max) node
tree.RightKey() // get the right-most (max) node's key
tree.RightValue() // get the right-most (max) node's value
}

View file

@ -0,0 +1,45 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/sets/treeset"
)
// User model (id and name)
type User struct {
id int
name string
}
// Comparator function (sort by IDs)
func byID(a, b interface{}) int {
// Type assertion, program will panic if this is not respected
c1 := a.(User)
c2 := b.(User)
switch {
case c1.id > c2.id:
return 1
case c1.id < c2.id:
return -1
default:
return 0
}
}
// CustomComparatorExample to demonstrate basic usage of CustomComparator
func CustomComparatorExample() {
set := treeset.NewWith(byID)
set.Add(User{2, "Second"})
set.Add(User{3, "Third"})
set.Add(User{1, "First"})
set.Add(User{4, "Fourth"})
fmt.Println(set) // {1 First}, {2 Second}, {3 Third}, {4 Fourth}
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
dll "github.com/emirpasic/gods/lists/doublylinkedlist"
"github.com/emirpasic/gods/utils"
)
// DoublyLinkedListExample to demonstrate basic usage of DoublyLinkedList
func DoublyLinkedListExample() {
list := dll.New()
list.Add("a") // ["a"]
list.Append("b") // ["a","b"] (same as Add())
list.Prepend("c") // ["c","a","b"]
list.Sort(utils.StringComparator) // ["a","b","c"]
_, _ = list.Get(0) // "a",true
_, _ = list.Get(100) // nil,false
_ = list.Contains("a", "b", "c") // true
_ = list.Contains("a", "b", "c", "d") // false
list.Remove(2) // ["a","b"]
list.Remove(1) // ["a"]
list.Remove(0) // []
list.Remove(0) // [] (ignored)
_ = list.Empty() // true
_ = list.Size() // 0
list.Add("a") // ["a"]
list.Clear() // []
}

View file

@ -0,0 +1,59 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/sets/treeset"
)
func printSet(txt string, set *treeset.Set) {
fmt.Print(txt, "[ ")
set.Each(func(index int, value interface{}) {
fmt.Print(value, " ")
})
fmt.Println("]")
}
// EnumerableWithIndexExample to demonstrate basic usage of EnumerableWithIndex
func EnumerableWithIndexExample() {
set := treeset.NewWithIntComparator()
set.Add(2, 3, 4, 2, 5, 6, 7, 8)
printSet("Initial", set) // [ 2 3 4 5 6 7 8 ]
even := set.Select(func(index int, value interface{}) bool {
return value.(int)%2 == 0
})
printSet("Even numbers", even) // [ 2 4 6 8 ]
foundIndex, foundValue := set.Find(func(index int, value interface{}) bool {
return value.(int)%2 == 0 && value.(int)%3 == 0
})
if foundIndex != -1 {
fmt.Println("Number divisible by 2 and 3 found is", foundValue, "at index", foundIndex) // value: 6, index: 4
}
square := set.Map(func(index int, value interface{}) interface{} {
return value.(int) * value.(int)
})
printSet("Numbers squared", square) // [ 4 9 16 25 36 49 64 ]
bigger := set.Any(func(index int, value interface{}) bool {
return value.(int) > 5
})
fmt.Println("Set contains a number bigger than 5 is ", bigger) // true
positive := set.All(func(index int, value interface{}) bool {
return value.(int) > 0
})
fmt.Println("All numbers are positive is", positive) // true
evenNumbersSquared := set.Select(func(index int, value interface{}) bool {
return value.(int)%2 == 0
}).Map(func(index int, value interface{}) interface{} {
return value.(int) * value.(int)
})
printSet("Chaining", evenNumbersSquared) // [ 4 16 36 64 ]
}

View file

@ -0,0 +1,65 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/maps/treemap"
)
func printMap(txt string, m *treemap.Map) {
fmt.Print(txt, " { ")
m.Each(func(key interface{}, value interface{}) {
fmt.Print(key, ":", value, " ")
})
fmt.Println("}")
}
// EunumerableWithKeyExample to demonstrate basic usage of EunumerableWithKey
func EunumerableWithKeyExample() {
m := treemap.NewWithStringComparator()
m.Put("g", 7)
m.Put("f", 6)
m.Put("e", 5)
m.Put("d", 4)
m.Put("c", 3)
m.Put("b", 2)
m.Put("a", 1)
printMap("Initial", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 }
even := m.Select(func(key interface{}, value interface{}) bool {
return value.(int)%2 == 0
})
printMap("Elements with even values", even) // { b:2 d:4 f:6 }
foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool {
return value.(int)%2 == 0 && value.(int)%3 == 0
})
if foundKey != nil {
fmt.Println("Element with value divisible by 2 and 3 found is", foundValue, "with key", foundKey) // value: 6, index: 4
}
square := m.Map(func(key interface{}, value interface{}) (interface{}, interface{}) {
return key.(string) + key.(string), value.(int) * value.(int)
})
printMap("Elements' values squared and letters duplicated", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 }
bigger := m.Any(func(key interface{}, value interface{}) bool {
return value.(int) > 5
})
fmt.Println("Map contains element whose value is bigger than 5 is", bigger) // true
positive := m.All(func(key interface{}, value interface{}) bool {
return value.(int) > 0
})
fmt.Println("All map's elements have positive values is", positive) // true
evenNumbersSquared := m.Select(func(key interface{}, value interface{}) bool {
return value.(int)%2 == 0
}).Map(func(key interface{}, value interface{}) (interface{}, interface{}) {
return key, value.(int) * value.(int)
})
printMap("Chaining", evenNumbersSquared) // { b:4 d:16 f:36 }
}

View file

@ -0,0 +1,25 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/maps/hashbidimap"
// HashBidiMapExample to demonstrate basic usage of HashMap
func HashBidiMapExample() {
m := hashbidimap.New() // empty
m.Put(1, "x") // 1->x
m.Put(3, "b") // 1->x, 3->b (random order)
m.Put(1, "a") // 1->a, 3->b (random order)
m.Put(2, "b") // 1->a, 2->b (random order)
_, _ = m.GetKey("a") // 1, true
_, _ = m.Get(2) // b, true
_, _ = m.Get(3) // nil, false
_ = m.Values() // []interface {}{"a", "b"} (random order)
_ = m.Keys() // []interface {}{1, 2} (random order)
m.Remove(1) // 2->b
m.Clear() // empty
m.Empty() // true
m.Size() // 0
}

23
vendor/github.com/emirpasic/gods/examples/hashmap.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/maps/hashmap"
// HashMapExample to demonstrate basic usage of HashMap
func HashMapExample() {
m := hashmap.New() // empty
m.Put(1, "x") // 1->x
m.Put(2, "b") // 2->b, 1->x (random order)
m.Put(1, "a") // 2->b, 1->a (random order)
_, _ = m.Get(2) // b, true
_, _ = m.Get(3) // nil, false
_ = m.Values() // []interface {}{"b", "a"} (random order)
_ = m.Keys() // []interface {}{1, 2} (random order)
m.Remove(1) // 2->b
m.Clear() // empty
m.Empty() // true
m.Size() // 0
}

23
vendor/github.com/emirpasic/gods/examples/hashset.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/sets/hashset"
// HashSetExample to demonstrate basic usage of HashSet
func HashSetExample() {
set := hashset.New() // empty (keys are of type int)
set.Add(1) // 1
set.Add(2, 2, 3, 4, 5) // 3, 1, 2, 4, 5 (random order, duplicates ignored)
set.Remove(4) // 5, 3, 2, 1 (random order)
set.Remove(2, 3) // 1, 5 (random order)
set.Contains(1) // true
set.Contains(1, 5) // true
set.Contains(1, 6) // false
_ = set.Values() // []int{5,1} (random order)
set.Clear() // empty
set.Empty() // true
set.Size() // 0
}

View file

@ -0,0 +1,51 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/sets/treeset"
)
// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex
func IteratorWithIndexExample() {
set := treeset.NewWithStringComparator()
set.Add("a", "b", "c")
it := set.Iterator()
fmt.Print("\nForward iteration\n")
for it.Next() {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nForward iteration (again)\n")
for it.Begin(); it.Next(); {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nBackward iteration\n")
for it.Prev() {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a]
}
fmt.Print("\nBackward iteration (again)\n")
for it.End(); it.Prev(); {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a]
}
if it.First() {
fmt.Print("\nFirst index: ", it.Index()) // First index: 0
fmt.Print("\nFirst value: ", it.Value()) // First value: a
}
if it.Last() {
fmt.Print("\nLast index: ", it.Index()) // Last index: 3
fmt.Print("\nLast value: ", it.Value()) // Last value: c
}
}

View file

@ -0,0 +1,53 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
"github.com/emirpasic/gods/maps/treemap"
)
// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey
func IteratorWithKeyExample() {
m := treemap.NewWithIntComparator()
m.Put(1, "a")
m.Put(2, "b")
m.Put(3, "a")
it := m.Iterator()
fmt.Print("\nForward iteration\n")
for it.Next() {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nForward iteration (again)\n")
for it.Begin(); it.Next(); {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nBackward iteration\n")
for it.Prev() {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a]
}
fmt.Print("\nBackward iteration (again)\n")
for it.End(); it.Prev(); {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a]
}
if it.First() {
fmt.Print("\nFirst key: ", it.Key()) // First key: 0
fmt.Print("\nFirst value: ", it.Value()) // First value: a
}
if it.Last() {
fmt.Print("\nLast key: ", it.Key()) // Last key: 3
fmt.Print("\nLast value: ", it.Value()) // Last value: c
}
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import lls "github.com/emirpasic/gods/stacks/linkedliststack"
// LinkedListStackExample to demonstrate basic usage of LinkedListStack
func LinkedListStackExample() {
stack := lls.New() // empty
stack.Push(1) // 1
stack.Push(2) // 1, 2
stack.Values() // 2, 1 (LIFO order)
_, _ = stack.Peek() // 2,true
_, _ = stack.Pop() // 2, true
_, _ = stack.Pop() // 1, true
_, _ = stack.Pop() // nil, false (nothing to pop)
stack.Push(1) // 1
stack.Clear() // empty
stack.Empty() // true
stack.Size() // 0
}

View file

@ -0,0 +1,50 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
// RedBlackTreeExample to demonstrate basic usage of RedBlackTree
func RedBlackTreeExample() {
tree := rbt.NewWithIntComparator() // empty(keys are of type int)
tree.Put(1, "x") // 1->x
tree.Put(2, "b") // 1->x, 2->b (in order)
tree.Put(1, "a") // 1->a, 2->b (in order, replacement)
tree.Put(3, "c") // 1->a, 2->b, 3->c (in order)
tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order)
tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)
tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
//
// RedBlackTree
// │ ┌── 6
// │ ┌── 5
// │ ┌── 4
// │ │ └── 3
// └── 2
// └── 1
_ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f"} (in order)
_ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order)
tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)
fmt.Println(tree)
//
// RedBlackTree
// │ ┌── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 1
tree.Clear() // empty
tree.Empty() // true
tree.Size() // 0
}

View file

@ -0,0 +1,113 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"fmt"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
// RedBlackTreeExtended to demonstrate how to extend a RedBlackTree to include new functions
type RedBlackTreeExtended struct {
*rbt.Tree
}
// GetMin gets the min value and flag if found
func (tree *RedBlackTreeExtended) GetMin() (value interface{}, found bool) {
node, found := tree.getMinFromNode(tree.Root)
if node != nil {
return node.Value, found
}
return nil, false
}
// GetMax gets the max value and flag if found
func (tree *RedBlackTreeExtended) GetMax() (value interface{}, found bool) {
node, found := tree.getMaxFromNode(tree.Root)
if node != nil {
return node.Value, found
}
return nil, false
}
// RemoveMin removes the min value and flag if found
func (tree *RedBlackTreeExtended) RemoveMin() (value interface{}, deleted bool) {
node, found := tree.getMinFromNode(tree.Root)
if found {
tree.Remove(node.Key)
return node.Value, found
}
return nil, false
}
// RemoveMax removes the max value and flag if found
func (tree *RedBlackTreeExtended) RemoveMax() (value interface{}, deleted bool) {
node, found := tree.getMaxFromNode(tree.Root)
if found {
tree.Remove(node.Key)
return node.Value, found
}
return nil, false
}
func (tree *RedBlackTreeExtended) getMinFromNode(node *rbt.Node) (foundNode *rbt.Node, found bool) {
if node == nil {
return nil, false
}
if node.Left == nil {
return node, true
}
return tree.getMinFromNode(node.Left)
}
func (tree *RedBlackTreeExtended) getMaxFromNode(node *rbt.Node) (foundNode *rbt.Node, found bool) {
if node == nil {
return nil, false
}
if node.Right == nil {
return node, true
}
return tree.getMaxFromNode(node.Right)
}
func print(tree *RedBlackTreeExtended) {
max, _ := tree.GetMax()
min, _ := tree.GetMin()
fmt.Printf("Value for max key: %v \n", max)
fmt.Printf("Value for min key: %v \n", min)
fmt.Println(tree)
}
// RedBlackTreeExtendedExample main method on how to use the custom red-black tree above
func RedBlackTreeExtendedExample() {
tree := RedBlackTreeExtended{rbt.NewWithIntComparator()}
tree.Put(1, "a") // 1->x (in order)
tree.Put(2, "b") // 1->x, 2->b (in order)
tree.Put(3, "c") // 1->x, 2->b, 3->c (in order)
tree.Put(4, "d") // 1->x, 2->b, 3->c, 4->d (in order)
tree.Put(5, "e") // 1->x, 2->b, 3->c, 4->d, 5->e (in order)
print(&tree)
// Value for max key: e
// Value for min key: a
// RedBlackTree
// │ ┌── 5
// │ ┌── 4
// │ │ └── 3
// └── 2
// └── 1
tree.RemoveMin() // 2->b, 3->c, 4->d, 5->e (in order)
tree.RemoveMax() // 2->b, 3->c, 4->d (in order)
tree.RemoveMin() // 3->c, 4->d (in order)
tree.RemoveMax() // 3->c (in order)
print(&tree)
// Value for max key: c
// Value for min key: c
// RedBlackTree
// └── 3
}

View file

@ -0,0 +1,51 @@
package examples
import (
"fmt"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/maps/hashmap"
)
// ListSerializationExample demonstrates how to serialize and deserialize lists to and from JSON
func ListSerializationExample() {
list := arraylist.New()
list.Add("a", "b", "c")
// Serialization (marshalling)
json, err := list.ToJSON()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(json)) // ["a","b","c"]
// Deserialization (unmarshalling)
json = []byte(`["a","b"]`)
err = list.FromJSON(json)
if err != nil {
fmt.Println(err)
}
fmt.Println(list) // ArrayList ["a","b"]
}
// MapSerializationExample demonstrates how to serialize and deserialize maps to and from JSON
func MapSerializationExample() {
m := hashmap.New()
m.Put("a", "1")
m.Put("b", "2")
m.Put("c", "3")
// Serialization (marshalling)
json, err := m.ToJSON()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(json)) // {"a":"1","b":"2","c":"3"}
// Deserialization (unmarshalling)
json = []byte(`{"a":"1","b":"2"}`)
err = m.FromJSON(json)
if err != nil {
fmt.Println(err)
}
fmt.Println(m) // HashMap {"a":"1","b":"2"}
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
sll "github.com/emirpasic/gods/lists/singlylinkedlist"
"github.com/emirpasic/gods/utils"
)
// SinglyLinkedListExample to demonstrate basic usage of SinglyLinkedList
func SinglyLinkedListExample() {
list := sll.New()
list.Add("a") // ["a"]
list.Append("b") // ["a","b"] (same as Add())
list.Prepend("c") // ["c","a","b"]
list.Sort(utils.StringComparator) // ["a","b","c"]
_, _ = list.Get(0) // "a",true
_, _ = list.Get(100) // nil,false
_ = list.Contains("a", "b", "c") // true
_ = list.Contains("a", "b", "c", "d") // false
list.Remove(2) // ["a","b"]
list.Remove(1) // ["a"]
list.Remove(0) // []
list.Remove(0) // [] (ignored)
_ = list.Empty() // true
_ = list.Size() // 0
list.Add("a") // ["a"]
list.Clear() // []
}

17
vendor/github.com/emirpasic/gods/examples/sort.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/utils"
// SortExample to demonstrate basic usage of basic sort
func SortExample() {
strings := []interface{}{} // []
strings = append(strings, "d") // ["d"]
strings = append(strings, "a") // ["d","a"]
strings = append(strings, "b") // ["d","a",b"
strings = append(strings, "c") // ["d","a",b","c"]
utils.Sort(strings, utils.StringComparator) // ["a","b","c","d"]
}

View file

@ -0,0 +1,28 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import (
"github.com/emirpasic/gods/maps/treebidimap"
"github.com/emirpasic/gods/utils"
)
// TreeBidiMapExample to demonstrate basic usage of TreeBidiMap
func TreeBidiMapExample() {
m := treebidimap.NewWith(utils.IntComparator, utils.StringComparator)
m.Put(1, "x") // 1->x
m.Put(3, "b") // 1->x, 3->b (ordered)
m.Put(1, "a") // 1->a, 3->b (ordered)
m.Put(2, "b") // 1->a, 2->b (ordered)
_, _ = m.GetKey("a") // 1, true
_, _ = m.Get(2) // b, true
_, _ = m.Get(3) // nil, false
_ = m.Values() // []interface {}{"a", "b"} (ordered)
_ = m.Keys() // []interface {}{1, 2} (ordered)
m.Remove(1) // 2->b
m.Clear() // empty
m.Empty() // true
m.Size() // 0
}

23
vendor/github.com/emirpasic/gods/examples/treemap.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/maps/treemap"
// TreeMapExample to demonstrate basic usage of TreeMap
func TreeMapExample() {
m := treemap.NewWithIntComparator() // empty (keys are of type int)
m.Put(1, "x") // 1->x
m.Put(2, "b") // 1->x, 2->b (in order)
m.Put(1, "a") // 1->a, 2->b (in order)
_, _ = m.Get(2) // b, true
_, _ = m.Get(3) // nil, false
_ = m.Values() // []interface {}{"a", "b"} (in order)
_ = m.Keys() // []interface {}{1, 2} (in order)
m.Remove(1) // 2->b
m.Clear() // empty
m.Empty() // true
m.Size() // 0
}

23
vendor/github.com/emirpasic/gods/examples/treeset.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package examples
import "github.com/emirpasic/gods/sets/treeset"
// TreeSetExample to demonstrate basic usage of TreeSet
func TreeSetExample() {
set := treeset.NewWithIntComparator() // empty
set.Add(1) // 1
set.Add(2, 2, 3, 4, 5) // 1, 2, 3, 4, 5 (in order, duplicates ignored)
set.Remove(4) // 1, 2, 3, 5 (in order)
set.Remove(2, 3) // 1, 5 (in order)
set.Contains(1) // true
set.Contains(1, 5) // true
set.Contains(1, 6) // false
_ = set.Values() // []int{1,5} (in order)
set.Clear() // empty
set.Empty() // true
set.Size() // 0
}

View file

@ -0,0 +1,200 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package arraylist implements the array list.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
package arraylist
import (
"fmt"
"github.com/emirpasic/gods/lists"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertListImplementation() {
var _ lists.List = (*List)(nil)
}
// List holds the elements in a slice
type List struct {
elements []interface{}
size int
}
const (
growthFactor = float32(2.0) // growth by 100%
shrinkFactor = float32(0.25) // shrink when size is 25% of capacity (0 means never shrink)
)
// New instantiates a new empty list
func New() *List {
return &List{}
}
// Add appends a value at the end of the list
func (list *List) Add(values ...interface{}) {
list.growBy(len(values))
for _, value := range values {
list.elements[list.size] = value
list.size++
}
}
// Get returns the element at index.
// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
func (list *List) Get(index int) (interface{}, bool) {
if !list.withinRange(index) {
return nil, false
}
return list.elements[index], true
}
// Remove removes one or more elements from the list with the supplied indices.
func (list *List) Remove(index int) {
if !list.withinRange(index) {
return
}
list.elements[index] = nil // cleanup reference
copy(list.elements[index:], list.elements[index+1:list.size]) // shift to the left by one (slow operation, need ways to optimize this)
list.size--
list.shrink()
}
// Contains checks if elements (one or more) are present in the set.
// All elements have to be present in the set for the method to return true.
// Performance time complexity of n^2.
// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
func (list *List) Contains(values ...interface{}) bool {
for _, searchValue := range values {
found := false
for _, element := range list.elements {
if element == searchValue {
found = true
break
}
}
if !found {
return false
}
}
return true
}
// Values returns all elements in the list.
func (list *List) Values() []interface{} {
newElements := make([]interface{}, list.size, list.size)
copy(newElements, list.elements[:list.size])
return newElements
}
// Empty returns true if list does not contain any elements.
func (list *List) Empty() bool {
return list.size == 0
}
// Size returns number of elements within the list.
func (list *List) Size() int {
return list.size
}
// Clear removes all elements from the list.
func (list *List) Clear() {
list.size = 0
list.elements = []interface{}{}
}
// Sort sorts values (in-place) using.
func (list *List) Sort(comparator utils.Comparator) {
if len(list.elements) < 2 {
return
}
utils.Sort(list.elements[:list.size], comparator)
}
// Swap swaps the two values at the specified positions.
func (list *List) Swap(i, j int) {
if list.withinRange(i) && list.withinRange(j) {
list.elements[i], list.elements[j] = list.elements[j], list.elements[i]
}
}
// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
// Does not do anything if position is negative or bigger than list's size
// Note: position equal to list's size is valid, i.e. append.
func (list *List) Insert(index int, values ...interface{}) {
if !list.withinRange(index) {
// Append
if index == list.size {
list.Add(values...)
}
return
}
l := len(values)
list.growBy(l)
list.size += l
// Shift old to right
for i := list.size - 1; i >= index+l; i-- {
list.elements[i] = list.elements[i-l]
}
// Insert new
for i, value := range values {
list.elements[index+i] = value
}
}
// String returns a string representation of container
func (list *List) String() string {
str := "ArrayList\n"
values := []string{}
for _, value := range list.elements[:list.size] {
values = append(values, fmt.Sprintf("%v", value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (list *List) withinRange(index int) bool {
return index >= 0 && index < list.size
}
func (list *List) resize(cap int) {
newElements := make([]interface{}, cap, cap)
copy(newElements, list.elements)
list.elements = newElements
}
// Expand the array if necessary, i.e. capacity will be reached if we add n elements
func (list *List) growBy(n int) {
// When capacity is reached, grow by a factor of growthFactor and add number of elements
currentCapacity := cap(list.elements)
if list.size+n >= currentCapacity {
newCapacity := int(growthFactor * float32(currentCapacity+n))
list.resize(newCapacity)
}
}
// Shrink the array if necessary, i.e. when size is shrinkFactor percent of current capacity
func (list *List) shrink() {
if shrinkFactor == 0.0 {
return
}
// Shrink when size is at shrinkFactor * capacity
currentCapacity := cap(list.elements)
if list.size <= int(float32(currentCapacity)*shrinkFactor) {
list.resize(list.size)
}
}

View file

@ -0,0 +1,606 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraylist
import (
"fmt"
"github.com/emirpasic/gods/utils"
"testing"
)
func TestListAdd(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue := list.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := list.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListRemove(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
list.Remove(2)
if actualValue, ok := list.Get(2); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
list.Remove(1)
list.Remove(0)
list.Remove(0) // no effect
if actualValue := list.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestListGet(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue, ok := list.Get(0); actualValue != "a" || !ok {
t.Errorf("Got %v expected %v", actualValue, "a")
}
if actualValue, ok := list.Get(1); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
if actualValue, ok := list.Get(3); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
list.Remove(0)
if actualValue, ok := list.Get(0); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
}
func TestListSwap(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
list.Swap(0, 1)
if actualValue, ok := list.Get(0); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListSort(t *testing.T) {
list := New()
list.Sort(utils.StringComparator)
list.Add("e", "f", "g", "a", "b", "c", "d")
list.Sort(utils.StringComparator)
for i := 1; i < list.Size(); i++ {
a, _ := list.Get(i - 1)
b, _ := list.Get(i)
if a.(string) > b.(string) {
t.Errorf("Not sorted! %s > %s", a, b)
}
}
}
func TestListClear(t *testing.T) {
list := New()
list.Add("e", "f", "g", "a", "b", "c", "d")
list.Clear()
if actualValue := list.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestListContains(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue := list.Contains("a"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Contains("a", "b", "c"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Contains("a", "b", "c", "d"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
list.Clear()
if actualValue := list.Contains("a"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := list.Contains("a", "b", "c"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
}
func TestListValues(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListInsert(t *testing.T) {
list := New()
list.Insert(0, "b", "c")
list.Insert(0, "a")
list.Insert(10, "x") // ignore
if actualValue := list.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
list.Insert(3, "d") // append
if actualValue := list.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", list.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListEach(t *testing.T) {
list := New()
list.Add("a", "b", "c")
list.Each(func(index int, value interface{}) {
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
})
}
func TestListMap(t *testing.T) {
list := New()
list.Add("a", "b", "c")
mappedList := list.Map(func(index int, value interface{}) interface{} {
return "mapped: " + value.(string)
})
if actualValue, _ := mappedList.Get(0); actualValue != "mapped: a" {
t.Errorf("Got %v expected %v", actualValue, "mapped: a")
}
if actualValue, _ := mappedList.Get(1); actualValue != "mapped: b" {
t.Errorf("Got %v expected %v", actualValue, "mapped: b")
}
if actualValue, _ := mappedList.Get(2); actualValue != "mapped: c" {
t.Errorf("Got %v expected %v", actualValue, "mapped: c")
}
if mappedList.Size() != 3 {
t.Errorf("Got %v expected %v", mappedList.Size(), 3)
}
}
func TestListSelect(t *testing.T) {
list := New()
list.Add("a", "b", "c")
selectedList := list.Select(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if actualValue, _ := selectedList.Get(0); actualValue != "a" {
t.Errorf("Got %v expected %v", actualValue, "value: a")
}
if actualValue, _ := selectedList.Get(1); actualValue != "b" {
t.Errorf("Got %v expected %v", actualValue, "value: b")
}
if selectedList.Size() != 2 {
t.Errorf("Got %v expected %v", selectedList.Size(), 3)
}
}
func TestListAny(t *testing.T) {
list := New()
list.Add("a", "b", "c")
any := list.Any(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if any != true {
t.Errorf("Got %v expected %v", any, true)
}
any = list.Any(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if any != false {
t.Errorf("Got %v expected %v", any, false)
}
}
func TestListAll(t *testing.T) {
list := New()
list.Add("a", "b", "c")
all := list.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "c"
})
if all != true {
t.Errorf("Got %v expected %v", all, true)
}
all = list.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if all != false {
t.Errorf("Got %v expected %v", all, false)
}
}
func TestListFind(t *testing.T) {
list := New()
list.Add("a", "b", "c")
foundIndex, foundValue := list.Find(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if foundValue != "c" || foundIndex != 2 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2)
}
foundIndex, foundValue = list.Find(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if foundValue != nil || foundIndex != -1 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil)
}
}
func TestListChaining(t *testing.T) {
list := New()
list.Add("a", "b", "c")
chainedList := list.Select(func(index int, value interface{}) bool {
return value.(string) > "a"
}).Map(func(index int, value interface{}) interface{} {
return value.(string) + value.(string)
})
if chainedList.Size() != 2 {
t.Errorf("Got %v expected %v", chainedList.Size(), 2)
}
if actualValue, ok := chainedList.Get(0); actualValue != "bb" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := chainedList.Get(1); actualValue != "cc" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListIteratorNextOnEmpty(t *testing.T) {
list := New()
it := list.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty list")
}
}
func TestListIteratorNext(t *testing.T) {
list := New()
list.Add("a", "b", "c")
it := list.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListIteratorPrevOnEmpty(t *testing.T) {
list := New()
it := list.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty list")
}
}
func TestListIteratorPrev(t *testing.T) {
list := New()
list.Add("a", "b", "c")
it := list.Iterator()
for it.Next() {
}
count := 0
for it.Prev() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListIteratorBegin(t *testing.T) {
list := New()
it := list.Iterator()
it.Begin()
list.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorEnd(t *testing.T) {
list := New()
it := list.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
list.Add("a", "b", "c")
it.End()
if index := it.Index(); index != list.Size() {
t.Errorf("Got %v expected %v", index, list.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c")
}
}
func TestListIteratorFirst(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorLast(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c")
}
}
func TestListSerialization(t *testing.T) {
list := New()
list.Add("a", "b", "c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := list.ToJSON()
assert()
err = list.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Get(n)
}
}
}
func benchmarkAdd(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Remove(n)
}
}
}
func BenchmarkArrayListGet100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListGet1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListGet10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListGet100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkArrayListAdd100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkArrayListRemove100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkArrayListRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkArrayListRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkArrayListRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}

View file

@ -0,0 +1,79 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraylist
import "github.com/emirpasic/gods/containers"
func assertEnumerableImplementation() {
var _ containers.EnumerableWithIndex = (*List)(nil)
}
// Each calls the given function once for each element, passing that element's index and value.
func (list *List) Each(f func(index int, value interface{})) {
iterator := list.Iterator()
for iterator.Next() {
f(iterator.Index(), iterator.Value())
}
}
// Map invokes the given function once for each element and returns a
// container containing the values returned by the given function.
func (list *List) Map(f func(index int, value interface{}) interface{}) *List {
newList := &List{}
iterator := list.Iterator()
for iterator.Next() {
newList.Add(f(iterator.Index(), iterator.Value()))
}
return newList
}
// Select returns a new container containing all elements for which the given function returns a true value.
func (list *List) Select(f func(index int, value interface{}) bool) *List {
newList := &List{}
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
newList.Add(iterator.Value())
}
}
return newList
}
// Any passes each element of the collection to the given function and
// returns true if the function ever returns true for any element.
func (list *List) Any(f func(index int, value interface{}) bool) bool {
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return true
}
}
return false
}
// All passes each element of the collection to the given function and
// returns true if the function returns true for all elements.
func (list *List) All(f func(index int, value interface{}) bool) bool {
iterator := list.Iterator()
for iterator.Next() {
if !f(iterator.Index(), iterator.Value()) {
return false
}
}
return true
}
// Find passes each element of the container to the given function and returns
// the first (index,value) for which the function is true or -1,nil otherwise
// if no element matches the criteria.
func (list *List) Find(f func(index int, value interface{}) bool) (int, interface{}) {
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return iterator.Index(), iterator.Value()
}
}
return -1, nil
}

View file

@ -0,0 +1,83 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraylist
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
list *List
index int
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (list *List) Iterator() Iterator {
return Iterator{list: list, index: -1}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.list.size {
iterator.index++
}
return iterator.list.withinRange(iterator.index)
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
return iterator.list.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.list.elements[iterator.index]
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.list.size
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,29 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraylist
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*List)(nil)
var _ containers.JSONDeserializer = (*List)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (list *List) ToJSON() ([]byte, error) {
return json.Marshal(list.elements[:list.size])
}
// FromJSON populates list's elements from the input JSON representation.
func (list *List) FromJSON(data []byte) error {
err := json.Unmarshal(data, &list.elements)
if err == nil {
list.size = len(list.elements)
}
return err
}

View file

@ -0,0 +1,296 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package doublylinkedlist implements the doubly-linked list.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
package doublylinkedlist
import (
"fmt"
"github.com/emirpasic/gods/lists"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertListImplementation() {
var _ lists.List = (*List)(nil)
}
// List holds the elements, where each element points to the next and previous element
type List struct {
first *element
last *element
size int
}
type element struct {
value interface{}
prev *element
next *element
}
// New instantiates a new empty list
func New() *List {
return &List{}
}
// Add appends a value (one or more) at the end of the list (same as Append())
func (list *List) Add(values ...interface{}) {
for _, value := range values {
newElement := &element{value: value, prev: list.last}
if list.size == 0 {
list.first = newElement
list.last = newElement
} else {
list.last.next = newElement
list.last = newElement
}
list.size++
}
}
// Append appends a value (one or more) at the end of the list (same as Add())
func (list *List) Append(values ...interface{}) {
list.Add(values...)
}
// Prepend prepends a values (or more)
func (list *List) Prepend(values ...interface{}) {
// in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"]
for v := len(values) - 1; v >= 0; v-- {
newElement := &element{value: values[v], next: list.first}
if list.size == 0 {
list.first = newElement
list.last = newElement
} else {
list.first.prev = newElement
list.first = newElement
}
list.size++
}
}
// Get returns the element at index.
// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
func (list *List) Get(index int) (interface{}, bool) {
if !list.withinRange(index) {
return nil, false
}
// determine traveral direction, last to first or first to last
if list.size-index < index {
element := list.last
for e := list.size - 1; e != index; e, element = e-1, element.prev {
}
return element.value, true
}
element := list.first
for e := 0; e != index; e, element = e+1, element.next {
}
return element.value, true
}
// Remove removes one or more elements from the list with the supplied indices.
func (list *List) Remove(index int) {
if !list.withinRange(index) {
return
}
if list.size == 1 {
list.Clear()
return
}
var element *element
// determine traversal direction, last to first or first to last
if list.size-index < index {
element = list.last
for e := list.size - 1; e != index; e, element = e-1, element.prev {
}
} else {
element = list.first
for e := 0; e != index; e, element = e+1, element.next {
}
}
if element == list.first {
list.first = element.next
}
if element == list.last {
list.last = element.prev
}
if element.prev != nil {
element.prev.next = element.next
}
if element.next != nil {
element.next.prev = element.prev
}
element = nil
list.size--
}
// Contains check if values (one or more) are present in the set.
// All values have to be present in the set for the method to return true.
// Performance time complexity of n^2.
// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
func (list *List) Contains(values ...interface{}) bool {
if len(values) == 0 {
return true
}
if list.size == 0 {
return false
}
for _, value := range values {
found := false
for element := list.first; element != nil; element = element.next {
if element.value == value {
found = true
break
}
}
if !found {
return false
}
}
return true
}
// Values returns all elements in the list.
func (list *List) Values() []interface{} {
values := make([]interface{}, list.size, list.size)
for e, element := 0, list.first; element != nil; e, element = e+1, element.next {
values[e] = element.value
}
return values
}
// Empty returns true if list does not contain any elements.
func (list *List) Empty() bool {
return list.size == 0
}
// Size returns number of elements within the list.
func (list *List) Size() int {
return list.size
}
// Clear removes all elements from the list.
func (list *List) Clear() {
list.size = 0
list.first = nil
list.last = nil
}
// Sort sorts values (in-place) using.
func (list *List) Sort(comparator utils.Comparator) {
if list.size < 2 {
return
}
values := list.Values()
utils.Sort(values, comparator)
list.Clear()
list.Add(values...)
}
// Swap swaps values of two elements at the given indices.
func (list *List) Swap(i, j int) {
if list.withinRange(i) && list.withinRange(j) && i != j {
var element1, element2 *element
for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next {
switch e {
case i:
element1 = currentElement
case j:
element2 = currentElement
}
}
element1.value, element2.value = element2.value, element1.value
}
}
// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
// Does not do anything if position is negative or bigger than list's size
// Note: position equal to list's size is valid, i.e. append.
func (list *List) Insert(index int, values ...interface{}) {
if !list.withinRange(index) {
// Append
if index == list.size {
list.Add(values...)
}
return
}
list.size += len(values)
var beforeElement *element
var foundElement *element
// determine traversal direction, last to first or first to last
if list.size-index < index {
foundElement = list.last
for e := list.size - 1; e != index; e, foundElement = e-1, foundElement.prev {
beforeElement = foundElement.prev
}
} else {
foundElement = list.first
for e := 0; e != index; e, foundElement = e+1, foundElement.next {
beforeElement = foundElement
}
}
if foundElement == list.first {
oldNextElement := list.first
for i, value := range values {
newElement := &element{value: value}
if i == 0 {
list.first = newElement
} else {
newElement.prev = beforeElement
beforeElement.next = newElement
}
beforeElement = newElement
}
oldNextElement.prev = beforeElement
beforeElement.next = oldNextElement
} else {
oldNextElement := beforeElement.next
for _, value := range values {
newElement := &element{value: value}
newElement.prev = beforeElement
beforeElement.next = newElement
beforeElement = newElement
}
oldNextElement.prev = beforeElement
beforeElement.next = oldNextElement
}
}
// String returns a string representation of container
func (list *List) String() string {
str := "DoublyLinkedList\n"
values := []string{}
for element := list.first; element != nil; element = element.next {
values = append(values, fmt.Sprintf("%v", element.value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (list *List) withinRange(index int) bool {
return index >= 0 && index < list.size
}

View file

@ -0,0 +1,606 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package doublylinkedlist
import (
"fmt"
"github.com/emirpasic/gods/utils"
"testing"
)
func TestListAdd(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue := list.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := list.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListRemove(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
list.Remove(2)
if actualValue, ok := list.Get(2); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
list.Remove(1)
list.Remove(0)
list.Remove(0) // no effect
if actualValue := list.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestListGet(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue, ok := list.Get(0); actualValue != "a" || !ok {
t.Errorf("Got %v expected %v", actualValue, "a")
}
if actualValue, ok := list.Get(1); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
if actualValue, ok := list.Get(3); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
list.Remove(0)
if actualValue, ok := list.Get(0); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
}
func TestListSwap(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
list.Swap(0, 1)
if actualValue, ok := list.Get(0); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListSort(t *testing.T) {
list := New()
list.Sort(utils.StringComparator)
list.Add("e", "f", "g", "a", "b", "c", "d")
list.Sort(utils.StringComparator)
for i := 1; i < list.Size(); i++ {
a, _ := list.Get(i - 1)
b, _ := list.Get(i)
if a.(string) > b.(string) {
t.Errorf("Not sorted! %s > %s", a, b)
}
}
}
func TestListClear(t *testing.T) {
list := New()
list.Add("e", "f", "g", "a", "b", "c", "d")
list.Clear()
if actualValue := list.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestListContains(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue := list.Contains("a"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Contains("a", "b", "c"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Contains("a", "b", "c", "d"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
list.Clear()
if actualValue := list.Contains("a"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := list.Contains("a", "b", "c"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
}
func TestListValues(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListInsert(t *testing.T) {
list := New()
list.Insert(0, "b", "c")
list.Insert(0, "a")
list.Insert(10, "x") // ignore
if actualValue := list.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
list.Insert(3, "d") // append
if actualValue := list.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", list.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListEach(t *testing.T) {
list := New()
list.Add("a", "b", "c")
list.Each(func(index int, value interface{}) {
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
})
}
func TestListMap(t *testing.T) {
list := New()
list.Add("a", "b", "c")
mappedList := list.Map(func(index int, value interface{}) interface{} {
return "mapped: " + value.(string)
})
if actualValue, _ := mappedList.Get(0); actualValue != "mapped: a" {
t.Errorf("Got %v expected %v", actualValue, "mapped: a")
}
if actualValue, _ := mappedList.Get(1); actualValue != "mapped: b" {
t.Errorf("Got %v expected %v", actualValue, "mapped: b")
}
if actualValue, _ := mappedList.Get(2); actualValue != "mapped: c" {
t.Errorf("Got %v expected %v", actualValue, "mapped: c")
}
if mappedList.Size() != 3 {
t.Errorf("Got %v expected %v", mappedList.Size(), 3)
}
}
func TestListSelect(t *testing.T) {
list := New()
list.Add("a", "b", "c")
selectedList := list.Select(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if actualValue, _ := selectedList.Get(0); actualValue != "a" {
t.Errorf("Got %v expected %v", actualValue, "value: a")
}
if actualValue, _ := selectedList.Get(1); actualValue != "b" {
t.Errorf("Got %v expected %v", actualValue, "value: b")
}
if selectedList.Size() != 2 {
t.Errorf("Got %v expected %v", selectedList.Size(), 3)
}
}
func TestListAny(t *testing.T) {
list := New()
list.Add("a", "b", "c")
any := list.Any(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if any != true {
t.Errorf("Got %v expected %v", any, true)
}
any = list.Any(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if any != false {
t.Errorf("Got %v expected %v", any, false)
}
}
func TestListAll(t *testing.T) {
list := New()
list.Add("a", "b", "c")
all := list.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "c"
})
if all != true {
t.Errorf("Got %v expected %v", all, true)
}
all = list.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if all != false {
t.Errorf("Got %v expected %v", all, false)
}
}
func TestListFind(t *testing.T) {
list := New()
list.Add("a", "b", "c")
foundIndex, foundValue := list.Find(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if foundValue != "c" || foundIndex != 2 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2)
}
foundIndex, foundValue = list.Find(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if foundValue != nil || foundIndex != -1 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil)
}
}
func TestListChaining(t *testing.T) {
list := New()
list.Add("a", "b", "c")
chainedList := list.Select(func(index int, value interface{}) bool {
return value.(string) > "a"
}).Map(func(index int, value interface{}) interface{} {
return value.(string) + value.(string)
})
if chainedList.Size() != 2 {
t.Errorf("Got %v expected %v", chainedList.Size(), 2)
}
if actualValue, ok := chainedList.Get(0); actualValue != "bb" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := chainedList.Get(1); actualValue != "cc" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListIteratorNextOnEmpty(t *testing.T) {
list := New()
it := list.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty list")
}
}
func TestListIteratorNext(t *testing.T) {
list := New()
list.Add("a", "b", "c")
it := list.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListIteratorPrevOnEmpty(t *testing.T) {
list := New()
it := list.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty list")
}
}
func TestListIteratorPrev(t *testing.T) {
list := New()
list.Add("a", "b", "c")
it := list.Iterator()
for it.Next() {
}
count := 0
for it.Prev() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListIteratorBegin(t *testing.T) {
list := New()
it := list.Iterator()
it.Begin()
list.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorEnd(t *testing.T) {
list := New()
it := list.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
list.Add("a", "b", "c")
it.End()
if index := it.Index(); index != list.Size() {
t.Errorf("Got %v expected %v", index, list.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c")
}
}
func TestListIteratorFirst(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorLast(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c")
}
}
func TestListSerialization(t *testing.T) {
list := New()
list.Add("a", "b", "c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := list.ToJSON()
assert()
err = list.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Get(n)
}
}
}
func benchmarkAdd(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Remove(n)
}
}
}
func BenchmarkDoublyLinkedListGet100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListGet1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListGet10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListGet100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkDoublyLinkedListAdd100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkDoublyLinkedListRemove100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkDoublyLinkedListRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkDoublyLinkedListRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkDoublyLinkedListRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}

View file

@ -0,0 +1,79 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package doublylinkedlist
import "github.com/emirpasic/gods/containers"
func assertEnumerableImplementation() {
var _ containers.EnumerableWithIndex = (*List)(nil)
}
// Each calls the given function once for each element, passing that element's index and value.
func (list *List) Each(f func(index int, value interface{})) {
iterator := list.Iterator()
for iterator.Next() {
f(iterator.Index(), iterator.Value())
}
}
// Map invokes the given function once for each element and returns a
// container containing the values returned by the given function.
func (list *List) Map(f func(index int, value interface{}) interface{}) *List {
newList := &List{}
iterator := list.Iterator()
for iterator.Next() {
newList.Add(f(iterator.Index(), iterator.Value()))
}
return newList
}
// Select returns a new container containing all elements for which the given function returns a true value.
func (list *List) Select(f func(index int, value interface{}) bool) *List {
newList := &List{}
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
newList.Add(iterator.Value())
}
}
return newList
}
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
func (list *List) Any(f func(index int, value interface{}) bool) bool {
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return true
}
}
return false
}
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
func (list *List) All(f func(index int, value interface{}) bool) bool {
iterator := list.Iterator()
for iterator.Next() {
if !f(iterator.Index(), iterator.Value()) {
return false
}
}
return true
}
// Find passes each element of the container to the given function and returns
// the first (index,value) for which the function is true or -1,nil otherwise
// if no element matches the criteria.
func (list *List) Find(f func(index int, value interface{}) bool) (index int, value interface{}) {
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return iterator.Index(), iterator.Value()
}
}
return -1, nil
}

View file

@ -0,0 +1,104 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package doublylinkedlist
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
list *List
index int
element *element
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (list *List) Iterator() Iterator {
return Iterator{list: list, index: -1, element: nil}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.list.size {
iterator.index++
}
if !iterator.list.withinRange(iterator.index) {
iterator.element = nil
return false
}
if iterator.index != 0 {
iterator.element = iterator.element.next
} else {
iterator.element = iterator.list.first
}
return true
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
if !iterator.list.withinRange(iterator.index) {
iterator.element = nil
return false
}
if iterator.index == iterator.list.size-1 {
iterator.element = iterator.list.last
} else {
iterator.element = iterator.element.prev
}
return iterator.list.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.element.value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
iterator.element = nil
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.list.size
iterator.element = iterator.list.last
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package doublylinkedlist
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*List)(nil)
var _ containers.JSONDeserializer = (*List)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (list *List) ToJSON() ([]byte, error) {
return json.Marshal(list.Values())
}
// FromJSON populates list's elements from the input JSON representation.
func (list *List) FromJSON(data []byte) error {
elements := []interface{}{}
err := json.Unmarshal(data, &elements)
if err == nil {
list.Clear()
list.Add(elements...)
}
return err
}

32
vendor/github.com/emirpasic/gods/lists/lists.go generated vendored Normal file
View file

@ -0,0 +1,32 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package lists provides an abstract List interface.
//
// In computer science, a list or sequence is an abstract data type that represents an ordered sequence of values, where the same value may occur more than once. An instance of a list is a computer representation of the mathematical concept of a finite sequence; the (potentially) infinite analog of a list is a stream. Lists are a basic example of containers, as they contain other values. If the same value occurs multiple times, each occurrence is considered a distinct item.
//
// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
package lists
import (
"github.com/emirpasic/gods/containers"
"github.com/emirpasic/gods/utils"
)
// List interface that all lists implement
type List interface {
Get(index int) (interface{}, bool)
Remove(index int)
Add(values ...interface{})
Contains(values ...interface{}) bool
Sort(comparator utils.Comparator)
Swap(index1, index2 int)
Insert(index int, values ...interface{})
containers.Container
// Empty() bool
// Size() int
// Clear()
// Values() []interface{}
}

View file

@ -0,0 +1,79 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package singlylinkedlist
import "github.com/emirpasic/gods/containers"
func assertEnumerableImplementation() {
var _ containers.EnumerableWithIndex = (*List)(nil)
}
// Each calls the given function once for each element, passing that element's index and value.
func (list *List) Each(f func(index int, value interface{})) {
iterator := list.Iterator()
for iterator.Next() {
f(iterator.Index(), iterator.Value())
}
}
// Map invokes the given function once for each element and returns a
// container containing the values returned by the given function.
func (list *List) Map(f func(index int, value interface{}) interface{}) *List {
newList := &List{}
iterator := list.Iterator()
for iterator.Next() {
newList.Add(f(iterator.Index(), iterator.Value()))
}
return newList
}
// Select returns a new container containing all elements for which the given function returns a true value.
func (list *List) Select(f func(index int, value interface{}) bool) *List {
newList := &List{}
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
newList.Add(iterator.Value())
}
}
return newList
}
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
func (list *List) Any(f func(index int, value interface{}) bool) bool {
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return true
}
}
return false
}
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
func (list *List) All(f func(index int, value interface{}) bool) bool {
iterator := list.Iterator()
for iterator.Next() {
if !f(iterator.Index(), iterator.Value()) {
return false
}
}
return true
}
// Find passes each element of the container to the given function and returns
// the first (index,value) for which the function is true or -1,nil otherwise
// if no element matches the criteria.
func (list *List) Find(f func(index int, value interface{}) bool) (index int, value interface{}) {
iterator := list.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return iterator.Index(), iterator.Value()
}
}
return -1, nil
}

View file

@ -0,0 +1,70 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package singlylinkedlist
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.IteratorWithIndex = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
list *List
index int
element *element
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (list *List) Iterator() Iterator {
return Iterator{list: list, index: -1, element: nil}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.list.size {
iterator.index++
}
if !iterator.list.withinRange(iterator.index) {
iterator.element = nil
return false
}
if iterator.index == 0 {
iterator.element = iterator.list.first
} else {
iterator.element = iterator.element.next
}
return true
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.element.value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
iterator.element = nil
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package singlylinkedlist
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*List)(nil)
var _ containers.JSONDeserializer = (*List)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (list *List) ToJSON() ([]byte, error) {
return json.Marshal(list.Values())
}
// FromJSON populates list's elements from the input JSON representation.
func (list *List) FromJSON(data []byte) error {
elements := []interface{}{}
err := json.Unmarshal(data, &elements)
if err == nil {
list.Clear()
list.Add(elements...)
}
return err
}

View file

@ -0,0 +1,264 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package singlylinkedlist implements the singly-linked list.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29
package singlylinkedlist
import (
"fmt"
"github.com/emirpasic/gods/lists"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertListImplementation() {
var _ lists.List = (*List)(nil)
}
// List holds the elements, where each element points to the next element
type List struct {
first *element
last *element
size int
}
type element struct {
value interface{}
next *element
}
// New instantiates a new empty list
func New() *List {
return &List{}
}
// Add appends a value (one or more) at the end of the list (same as Append())
func (list *List) Add(values ...interface{}) {
for _, value := range values {
newElement := &element{value: value}
if list.size == 0 {
list.first = newElement
list.last = newElement
} else {
list.last.next = newElement
list.last = newElement
}
list.size++
}
}
// Append appends a value (one or more) at the end of the list (same as Add())
func (list *List) Append(values ...interface{}) {
list.Add(values...)
}
// Prepend prepends a values (or more)
func (list *List) Prepend(values ...interface{}) {
// in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"]
for v := len(values) - 1; v >= 0; v-- {
newElement := &element{value: values[v], next: list.first}
list.first = newElement
if list.size == 0 {
list.last = newElement
}
list.size++
}
}
// Get returns the element at index.
// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
func (list *List) Get(index int) (interface{}, bool) {
if !list.withinRange(index) {
return nil, false
}
element := list.first
for e := 0; e != index; e, element = e+1, element.next {
}
return element.value, true
}
// Remove removes one or more elements from the list with the supplied indices.
func (list *List) Remove(index int) {
if !list.withinRange(index) {
return
}
if list.size == 1 {
list.Clear()
return
}
var beforeElement *element
element := list.first
for e := 0; e != index; e, element = e+1, element.next {
beforeElement = element
}
if element == list.first {
list.first = element.next
}
if element == list.last {
list.last = beforeElement
}
if beforeElement != nil {
beforeElement.next = element.next
}
element = nil
list.size--
}
// Contains checks if values (one or more) are present in the set.
// All values have to be present in the set for the method to return true.
// Performance time complexity of n^2.
// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.
func (list *List) Contains(values ...interface{}) bool {
if len(values) == 0 {
return true
}
if list.size == 0 {
return false
}
for _, value := range values {
found := false
for element := list.first; element != nil; element = element.next {
if element.value == value {
found = true
break
}
}
if !found {
return false
}
}
return true
}
// Values returns all elements in the list.
func (list *List) Values() []interface{} {
values := make([]interface{}, list.size, list.size)
for e, element := 0, list.first; element != nil; e, element = e+1, element.next {
values[e] = element.value
}
return values
}
// Empty returns true if list does not contain any elements.
func (list *List) Empty() bool {
return list.size == 0
}
// Size returns number of elements within the list.
func (list *List) Size() int {
return list.size
}
// Clear removes all elements from the list.
func (list *List) Clear() {
list.size = 0
list.first = nil
list.last = nil
}
// Sort sort values (in-place) using.
func (list *List) Sort(comparator utils.Comparator) {
if list.size < 2 {
return
}
values := list.Values()
utils.Sort(values, comparator)
list.Clear()
list.Add(values...)
}
// Swap swaps values of two elements at the given indices.
func (list *List) Swap(i, j int) {
if list.withinRange(i) && list.withinRange(j) && i != j {
var element1, element2 *element
for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next {
switch e {
case i:
element1 = currentElement
case j:
element2 = currentElement
}
}
element1.value, element2.value = element2.value, element1.value
}
}
// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.
// Does not do anything if position is negative or bigger than list's size
// Note: position equal to list's size is valid, i.e. append.
func (list *List) Insert(index int, values ...interface{}) {
if !list.withinRange(index) {
// Append
if index == list.size {
list.Add(values...)
}
return
}
list.size += len(values)
var beforeElement *element
foundElement := list.first
for e := 0; e != index; e, foundElement = e+1, foundElement.next {
beforeElement = foundElement
}
if foundElement == list.first {
oldNextElement := list.first
for i, value := range values {
newElement := &element{value: value}
if i == 0 {
list.first = newElement
} else {
beforeElement.next = newElement
}
beforeElement = newElement
}
beforeElement.next = oldNextElement
} else {
oldNextElement := beforeElement.next
for _, value := range values {
newElement := &element{value: value}
beforeElement.next = newElement
beforeElement = newElement
}
beforeElement.next = oldNextElement
}
}
// String returns a string representation of container
func (list *List) String() string {
str := "SinglyLinkedList\n"
values := []string{}
for element := list.first; element != nil; element = element.next {
values = append(values, fmt.Sprintf("%v", element.value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (list *List) withinRange(index int) bool {
return index >= 0 && index < list.size
}

View file

@ -0,0 +1,525 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package singlylinkedlist
import (
"fmt"
"github.com/emirpasic/gods/utils"
"testing"
)
func TestListAdd(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue := list.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := list.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListRemove(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
list.Remove(2)
if actualValue, ok := list.Get(2); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
list.Remove(1)
list.Remove(0)
list.Remove(0) // no effect
if actualValue := list.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestListGet(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue, ok := list.Get(0); actualValue != "a" || !ok {
t.Errorf("Got %v expected %v", actualValue, "a")
}
if actualValue, ok := list.Get(1); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
if actualValue, ok := list.Get(3); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
list.Remove(0)
if actualValue, ok := list.Get(0); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
}
func TestListSwap(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
list.Swap(0, 1)
if actualValue, ok := list.Get(0); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListSort(t *testing.T) {
list := New()
list.Sort(utils.StringComparator)
list.Add("e", "f", "g", "a", "b", "c", "d")
list.Sort(utils.StringComparator)
for i := 1; i < list.Size(); i++ {
a, _ := list.Get(i - 1)
b, _ := list.Get(i)
if a.(string) > b.(string) {
t.Errorf("Not sorted! %s > %s", a, b)
}
}
}
func TestListClear(t *testing.T) {
list := New()
list.Add("e", "f", "g", "a", "b", "c", "d")
list.Clear()
if actualValue := list.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestListContains(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue := list.Contains("a"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Contains("a", "b", "c"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := list.Contains("a", "b", "c", "d"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
list.Clear()
if actualValue := list.Contains("a"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := list.Contains("a", "b", "c"); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
}
func TestListValues(t *testing.T) {
list := New()
list.Add("a")
list.Add("b", "c")
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListInsert(t *testing.T) {
list := New()
list.Insert(0, "b", "c")
list.Insert(0, "a")
list.Insert(10, "x") // ignore
if actualValue := list.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
list.Insert(3, "d") // append
if actualValue := list.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", list.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListEach(t *testing.T) {
list := New()
list.Add("a", "b", "c")
list.Each(func(index int, value interface{}) {
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
})
}
func TestListMap(t *testing.T) {
list := New()
list.Add("a", "b", "c")
mappedList := list.Map(func(index int, value interface{}) interface{} {
return "mapped: " + value.(string)
})
if actualValue, _ := mappedList.Get(0); actualValue != "mapped: a" {
t.Errorf("Got %v expected %v", actualValue, "mapped: a")
}
if actualValue, _ := mappedList.Get(1); actualValue != "mapped: b" {
t.Errorf("Got %v expected %v", actualValue, "mapped: b")
}
if actualValue, _ := mappedList.Get(2); actualValue != "mapped: c" {
t.Errorf("Got %v expected %v", actualValue, "mapped: c")
}
if mappedList.Size() != 3 {
t.Errorf("Got %v expected %v", mappedList.Size(), 3)
}
}
func TestListSelect(t *testing.T) {
list := New()
list.Add("a", "b", "c")
selectedList := list.Select(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if actualValue, _ := selectedList.Get(0); actualValue != "a" {
t.Errorf("Got %v expected %v", actualValue, "value: a")
}
if actualValue, _ := selectedList.Get(1); actualValue != "b" {
t.Errorf("Got %v expected %v", actualValue, "value: b")
}
if selectedList.Size() != 2 {
t.Errorf("Got %v expected %v", selectedList.Size(), 3)
}
}
func TestListAny(t *testing.T) {
list := New()
list.Add("a", "b", "c")
any := list.Any(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if any != true {
t.Errorf("Got %v expected %v", any, true)
}
any = list.Any(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if any != false {
t.Errorf("Got %v expected %v", any, false)
}
}
func TestListAll(t *testing.T) {
list := New()
list.Add("a", "b", "c")
all := list.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "c"
})
if all != true {
t.Errorf("Got %v expected %v", all, true)
}
all = list.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if all != false {
t.Errorf("Got %v expected %v", all, false)
}
}
func TestListFind(t *testing.T) {
list := New()
list.Add("a", "b", "c")
foundIndex, foundValue := list.Find(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if foundValue != "c" || foundIndex != 2 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2)
}
foundIndex, foundValue = list.Find(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if foundValue != nil || foundIndex != -1 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil)
}
}
func TestListChaining(t *testing.T) {
list := New()
list.Add("a", "b", "c")
chainedList := list.Select(func(index int, value interface{}) bool {
return value.(string) > "a"
}).Map(func(index int, value interface{}) interface{} {
return value.(string) + value.(string)
})
if chainedList.Size() != 2 {
t.Errorf("Got %v expected %v", chainedList.Size(), 2)
}
if actualValue, ok := chainedList.Get(0); actualValue != "bb" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := chainedList.Get(1); actualValue != "cc" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
}
func TestListIteratorNextOnEmpty(t *testing.T) {
list := New()
it := list.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty list")
}
}
func TestListIteratorNext(t *testing.T) {
list := New()
list.Add("a", "b", "c")
it := list.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestListIteratorBegin(t *testing.T) {
list := New()
it := list.Iterator()
it.Begin()
list.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorFirst(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListSerialization(t *testing.T) {
list := New()
list.Add("a", "b", "c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := list.ToJSON()
assert()
err = list.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Get(n)
}
}
}
func benchmarkAdd(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, list *List, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
list.Remove(n)
}
}
}
func BenchmarkSinglyLinkedListGet100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListGet1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListGet10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListGet100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkGet(b, list, size)
}
func BenchmarkSinglyLinkedListAdd100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkAdd(b, list, size)
}
func BenchmarkSinglyLinkedListRemove100(b *testing.B) {
b.StopTimer()
size := 100
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkSinglyLinkedListRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkSinglyLinkedListRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}
func BenchmarkSinglyLinkedListRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
list := New()
for n := 0; n < size; n++ {
list.Add(n)
}
b.StartTimer()
benchmarkRemove(b, list, size)
}

View file

@ -0,0 +1,102 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hashbidimap implements a bidirectional map backed by two hashmaps.
//
// A bidirectional map, or hash bag, is an associative data structure in which the (key,value) pairs form a one-to-one correspondence.
// Thus the binary relation is functional in each direction: value can also act as a key to key.
// A pair (a,b) thus provides a unique coupling between 'a' and 'b' so that 'b' can be found when 'a' is used as a key and 'a' can be found when 'b' is used as a key.
//
// Elements are unordered in the map.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/Bidirectional_map
package hashbidimap
import (
"fmt"
"github.com/emirpasic/gods/maps"
"github.com/emirpasic/gods/maps/hashmap"
)
func assertMapImplementation() {
var _ maps.BidiMap = (*Map)(nil)
}
// Map holds the elements in two hashmaps.
type Map struct {
forwardMap hashmap.Map
inverseMap hashmap.Map
}
// New instantiates a bidirectional map.
func New() *Map {
return &Map{*hashmap.New(), *hashmap.New()}
}
// Put inserts element into the map.
func (m *Map) Put(key interface{}, value interface{}) {
if valueByKey, ok := m.forwardMap.Get(key); ok {
m.inverseMap.Remove(valueByKey)
}
if keyByValue, ok := m.inverseMap.Get(value); ok {
m.forwardMap.Remove(keyByValue)
}
m.forwardMap.Put(key, value)
m.inverseMap.Put(value, key)
}
// Get searches the element in the map by key and returns its value or nil if key is not found in map.
// Second return parameter is true if key was found, otherwise false.
func (m *Map) Get(key interface{}) (value interface{}, found bool) {
return m.forwardMap.Get(key)
}
// GetKey searches the element in the map by value and returns its key or nil if value is not found in map.
// Second return parameter is true if value was found, otherwise false.
func (m *Map) GetKey(value interface{}) (key interface{}, found bool) {
return m.inverseMap.Get(value)
}
// Remove removes the element from the map by key.
func (m *Map) Remove(key interface{}) {
if value, found := m.forwardMap.Get(key); found {
m.forwardMap.Remove(key)
m.inverseMap.Remove(value)
}
}
// Empty returns true if map does not contain any elements
func (m *Map) Empty() bool {
return m.Size() == 0
}
// Size returns number of elements in the map.
func (m *Map) Size() int {
return m.forwardMap.Size()
}
// Keys returns all keys (random order).
func (m *Map) Keys() []interface{} {
return m.forwardMap.Keys()
}
// Values returns all values (random order).
func (m *Map) Values() []interface{} {
return m.inverseMap.Keys()
}
// Clear removes all elements from the map.
func (m *Map) Clear() {
m.forwardMap.Clear()
m.inverseMap.Clear()
}
// String returns a string representation of container
func (m *Map) String() string {
str := "HashBidiMap\n"
str += fmt.Sprintf("%v", m.forwardMap)
return str
}

View file

@ -0,0 +1,354 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package hashbidimap
import (
"fmt"
"testing"
)
func TestMapPut(t *testing.T) {
m := New()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
if actualValue := m.Size(); actualValue != 7 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// key,expectedValue,expectedFound
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
}
func TestMapRemove(t *testing.T) {
m := New()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
m.Remove(5)
m.Remove(6)
m.Remove(7)
m.Remove(8)
m.Remove(5)
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
tests2 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
}
for _, test := range tests2 {
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
m.Remove(1)
m.Remove(4)
m.Remove(2)
m.Remove(3)
m.Remove(2)
m.Remove(2)
if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
if actualValue := m.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
}
func TestMapGetKey(t *testing.T) {
m := New()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
// key,expectedValue,expectedFound
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{nil, "x", false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := m.GetKey(test[1])
if actualValue != test[0] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[0])
}
}
}
func TestMapSerialization(t *testing.T) {
m := New()
m.Put("a", 1.0)
m.Put("b", 2.0)
m.Put("c", 3.0)
var err error
assert := func() {
if actualValue, expectedValue := m.Keys(), []interface{}{"a", "b", "c"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{1.0, 2.0, 3.0}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := m.ToJSON()
assert()
err = m.FromJSON(json)
assert()
}
func sameElements(a []interface{}, b []interface{}) bool {
if len(a) != len(b) {
return false
}
for _, av := range a {
found := false
for _, bv := range b {
if av == bv {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Get(n)
}
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, n)
}
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkHashBidiMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashBidiMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashBidiMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashBidiMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashBidiMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashBidiMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

View file

@ -0,0 +1,33 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package hashbidimap
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Map)(nil)
var _ containers.JSONDeserializer = (*Map)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (m *Map) ToJSON() ([]byte, error) {
return m.forwardMap.ToJSON()
}
// FromJSON populates list's elements from the input JSON representation.
func (m *Map) FromJSON(data []byte) error {
elements := make(map[string]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
m.Clear()
for key, value := range elements {
m.Put(key, value)
}
}
return err
}

View file

@ -0,0 +1,92 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hashmap implements a map backed by a hash table.
//
// Elements are unordered in the map.
//
// Structure is not thread safe.
//
// Reference: http://en.wikipedia.org/wiki/Associative_array
package hashmap
import (
"fmt"
"github.com/emirpasic/gods/maps"
)
func assertMapImplementation() {
var _ maps.Map = (*Map)(nil)
}
// Map holds the elements in go's native map
type Map struct {
m map[interface{}]interface{}
}
// New instantiates a hash map.
func New() *Map {
return &Map{m: make(map[interface{}]interface{})}
}
// Put inserts element into the map.
func (m *Map) Put(key interface{}, value interface{}) {
m.m[key] = value
}
// Get searches the element in the map by key and returns its value or nil if key is not found in map.
// Second return parameter is true if key was found, otherwise false.
func (m *Map) Get(key interface{}) (value interface{}, found bool) {
value, found = m.m[key]
return
}
// Remove removes the element from the map by key.
func (m *Map) Remove(key interface{}) {
delete(m.m, key)
}
// Empty returns true if map does not contain any elements
func (m *Map) Empty() bool {
return m.Size() == 0
}
// Size returns number of elements in the map.
func (m *Map) Size() int {
return len(m.m)
}
// Keys returns all keys (random order).
func (m *Map) Keys() []interface{} {
keys := make([]interface{}, m.Size())
count := 0
for key := range m.m {
keys[count] = key
count++
}
return keys
}
// Values returns all values (random order).
func (m *Map) Values() []interface{} {
values := make([]interface{}, m.Size())
count := 0
for _, value := range m.m {
values[count] = value
count++
}
return values
}
// Clear removes all elements from the map.
func (m *Map) Clear() {
m.m = make(map[interface{}]interface{})
}
// String returns a string representation of container
func (m *Map) String() string {
str := "HashMap\n"
str += fmt.Sprintf("%v", m.m)
return str
}

View file

@ -0,0 +1,322 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package hashmap
import (
"fmt"
"testing"
)
func TestMapPut(t *testing.T) {
m := New()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
if actualValue := m.Size(); actualValue != 7 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// key,expectedValue,expectedFound
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
}
func TestMapRemove(t *testing.T) {
m := New()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
m.Remove(5)
m.Remove(6)
m.Remove(7)
m.Remove(8)
m.Remove(5)
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
tests2 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
}
for _, test := range tests2 {
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
m.Remove(1)
m.Remove(4)
m.Remove(2)
m.Remove(3)
m.Remove(2)
m.Remove(2)
if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
if actualValue := m.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
}
func TestMapSerialization(t *testing.T) {
m := New()
m.Put("a", 1.0)
m.Put("b", 2.0)
m.Put("c", 3.0)
var err error
assert := func() {
if actualValue, expectedValue := m.Keys(), []interface{}{"a", "b", "c"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{1.0, 2.0, 3.0}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := m.ToJSON()
assert()
err = m.FromJSON(json)
assert()
}
func sameElements(a []interface{}, b []interface{}) bool {
if len(a) != len(b) {
return false
}
for _, av := range a {
found := false
for _, bv := range b {
if av == bv {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Get(n)
}
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkHashMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkHashMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkHashMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkHashMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := New()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

View file

@ -0,0 +1,38 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package hashmap
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
"github.com/emirpasic/gods/utils"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Map)(nil)
var _ containers.JSONDeserializer = (*Map)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (m *Map) ToJSON() ([]byte, error) {
elements := make(map[string]interface{})
for key, value := range m.m {
elements[utils.ToString(key)] = value
}
return json.Marshal(&elements)
}
// FromJSON populates list's elements from the input JSON representation.
func (m *Map) FromJSON(data []byte) error {
elements := make(map[string]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
m.Clear()
for key, value := range elements {
m.m[key] = value
}
}
return err
}

39
vendor/github.com/emirpasic/gods/maps/maps.go generated vendored Normal file
View file

@ -0,0 +1,39 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package maps provides an abstract Map interface.
//
// In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears just once in the collection.
//
// Operations associated with this data type allow:
// - the addition of a pair to the collection
// - the removal of a pair from the collection
// - the modification of an existing pair
// - the lookup of a value associated with a particular key
//
// Reference: https://en.wikipedia.org/wiki/Associative_array
package maps
import "github.com/emirpasic/gods/containers"
// Map interface that all maps implement
type Map interface {
Put(key interface{}, value interface{})
Get(key interface{}) (value interface{}, found bool)
Remove(key interface{})
Keys() []interface{}
containers.Container
// Empty() bool
// Size() int
// Clear()
// Values() []interface{}
}
// BidiMap interface that all bidirectional maps implement (extends the Map interface)
type BidiMap interface {
GetKey(value interface{}) (key interface{}, found bool)
Map
}

View file

@ -0,0 +1,80 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treebidimap
import "github.com/emirpasic/gods/containers"
func assertEnumerableImplementation() {
var _ containers.EnumerableWithKey = (*Map)(nil)
}
// Each calls the given function once for each element, passing that element's key and value.
func (m *Map) Each(f func(key interface{}, value interface{})) {
iterator := m.Iterator()
for iterator.Next() {
f(iterator.Key(), iterator.Value())
}
}
// Map invokes the given function once for each element and returns a container
// containing the values returned by the given function as key/value pairs.
func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, interface{})) *Map {
newMap := NewWith(m.keyComparator, m.valueComparator)
iterator := m.Iterator()
for iterator.Next() {
key2, value2 := f(iterator.Key(), iterator.Value())
newMap.Put(key2, value2)
}
return newMap
}
// Select returns a new container containing all elements for which the given function returns a true value.
func (m *Map) Select(f func(key interface{}, value interface{}) bool) *Map {
newMap := NewWith(m.keyComparator, m.valueComparator)
iterator := m.Iterator()
for iterator.Next() {
if f(iterator.Key(), iterator.Value()) {
newMap.Put(iterator.Key(), iterator.Value())
}
}
return newMap
}
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
func (m *Map) Any(f func(key interface{}, value interface{}) bool) bool {
iterator := m.Iterator()
for iterator.Next() {
if f(iterator.Key(), iterator.Value()) {
return true
}
}
return false
}
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
func (m *Map) All(f func(key interface{}, value interface{}) bool) bool {
iterator := m.Iterator()
for iterator.Next() {
if !f(iterator.Key(), iterator.Value()) {
return false
}
}
return true
}
// Find passes each element of the container to the given function and returns
// the first (key,value) for which the function is true or nil,nil otherwise if no element
// matches the criteria.
func (m *Map) Find(f func(key interface{}, value interface{}) bool) (interface{}, interface{}) {
iterator := m.Iterator()
for iterator.Next() {
if f(iterator.Key(), iterator.Value()) {
return iterator.Key(), iterator.Value()
}
}
return nil, nil
}

View file

@ -0,0 +1,77 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treebidimap
import (
"github.com/emirpasic/gods/containers"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
iterator rbt.Iterator
}
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (m *Map) Iterator() Iterator {
return Iterator{iterator: m.forwardMap.Iterator()}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
return iterator.iterator.Next()
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
return iterator.iterator.Prev()
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.iterator.Value().(*data).value
}
// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} {
return iterator.iterator.Key()
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.iterator.Begin()
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.iterator.End()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
return iterator.iterator.First()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
return iterator.iterator.Last()
}

View file

@ -0,0 +1,39 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treebidimap
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
"github.com/emirpasic/gods/utils"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Map)(nil)
var _ containers.JSONDeserializer = (*Map)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (m *Map) ToJSON() ([]byte, error) {
elements := make(map[string]interface{})
it := m.Iterator()
for it.Next() {
elements[utils.ToString(it.Key())] = it.Value()
}
return json.Marshal(&elements)
}
// FromJSON populates list's elements from the input JSON representation.
func (m *Map) FromJSON(data []byte) error {
elements := make(map[string]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
m.Clear()
for key, value := range elements {
m.Put(key, value)
}
}
return err
}

View file

@ -0,0 +1,138 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package treebidimap implements a bidirectional map backed by two red-black tree.
//
// This structure guarantees that the map will be in both ascending key and value order.
//
// Other than key and value ordering, the goal with this structure is to avoid duplication of elements, which can be significant if contained elements are large.
//
// A bidirectional map, or hash bag, is an associative data structure in which the (key,value) pairs form a one-to-one correspondence.
// Thus the binary relation is functional in each direction: value can also act as a key to key.
// A pair (a,b) thus provides a unique coupling between 'a' and 'b' so that 'b' can be found when 'a' is used as a key and 'a' can be found when 'b' is used as a key.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/Bidirectional_map
package treebidimap
import (
"fmt"
"github.com/emirpasic/gods/maps"
"github.com/emirpasic/gods/trees/redblacktree"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertMapImplementation() {
var _ maps.BidiMap = (*Map)(nil)
}
// Map holds the elements in two red-black trees.
type Map struct {
forwardMap redblacktree.Tree
inverseMap redblacktree.Tree
keyComparator utils.Comparator
valueComparator utils.Comparator
}
type data struct {
key interface{}
value interface{}
}
// NewWith instantiates a bidirectional map.
func NewWith(keyComparator utils.Comparator, valueComparator utils.Comparator) *Map {
return &Map{
forwardMap: *redblacktree.NewWith(keyComparator),
inverseMap: *redblacktree.NewWith(valueComparator),
keyComparator: keyComparator,
valueComparator: valueComparator,
}
}
// NewWithIntComparators instantiates a bidirectional map with the IntComparator for key and value, i.e. keys and values are of type int.
func NewWithIntComparators() *Map {
return NewWith(utils.IntComparator, utils.IntComparator)
}
// NewWithStringComparators instantiates a bidirectional map with the StringComparator for key and value, i.e. keys and values are of type string.
func NewWithStringComparators() *Map {
return NewWith(utils.StringComparator, utils.StringComparator)
}
// Put inserts element into the map.
func (m *Map) Put(key interface{}, value interface{}) {
if d, ok := m.forwardMap.Get(key); ok {
m.inverseMap.Remove(d.(*data).value)
}
if d, ok := m.inverseMap.Get(value); ok {
m.forwardMap.Remove(d.(*data).key)
}
d := &data{key: key, value: value}
m.forwardMap.Put(key, d)
m.inverseMap.Put(value, d)
}
// Get searches the element in the map by key and returns its value or nil if key is not found in map.
// Second return parameter is true if key was found, otherwise false.
func (m *Map) Get(key interface{}) (value interface{}, found bool) {
if d, ok := m.forwardMap.Get(key); ok {
return d.(*data).value, true
}
return nil, false
}
// GetKey searches the element in the map by value and returns its key or nil if value is not found in map.
// Second return parameter is true if value was found, otherwise false.
func (m *Map) GetKey(value interface{}) (key interface{}, found bool) {
if d, ok := m.inverseMap.Get(value); ok {
return d.(*data).key, true
}
return nil, false
}
// Remove removes the element from the map by key.
func (m *Map) Remove(key interface{}) {
if d, found := m.forwardMap.Get(key); found {
m.forwardMap.Remove(key)
m.inverseMap.Remove(d.(*data).value)
}
}
// Empty returns true if map does not contain any elements
func (m *Map) Empty() bool {
return m.Size() == 0
}
// Size returns number of elements in the map.
func (m *Map) Size() int {
return m.forwardMap.Size()
}
// Keys returns all keys (ordered).
func (m *Map) Keys() []interface{} {
return m.forwardMap.Keys()
}
// Values returns all values (ordered).
func (m *Map) Values() []interface{} {
return m.inverseMap.Keys()
}
// Clear removes all elements from the map.
func (m *Map) Clear() {
m.forwardMap.Clear()
m.inverseMap.Clear()
}
// String returns a string representation of container
func (m *Map) String() string {
str := "TreeBidiMap\nmap["
it := m.Iterator()
for it.Next() {
str += fmt.Sprintf("%v:%v ", it.Key(), it.Value())
}
return strings.TrimRight(str, " ") + "]"
}

View file

@ -0,0 +1,658 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treebidimap
import (
"fmt"
"github.com/emirpasic/gods/utils"
"testing"
)
func TestMapPut(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
if actualValue := m.Size(); actualValue != 7 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// key,expectedValue,expectedFound
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
}
func TestMapRemove(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
m.Remove(5)
m.Remove(6)
m.Remove(7)
m.Remove(8)
m.Remove(5)
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
tests2 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
}
for _, test := range tests2 {
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
m.Remove(1)
m.Remove(4)
m.Remove(2)
m.Remove(3)
m.Remove(2)
m.Remove(2)
if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
if actualValue := m.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
}
func TestMapGetKey(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
// key,expectedValue,expectedFound
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{nil, "x", false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := m.GetKey(test[1])
if actualValue != test[0] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[0])
}
}
}
func sameElements(a []interface{}, b []interface{}) bool {
if len(a) != len(b) {
return false
}
for _, av := range a {
found := false
for _, bv := range b {
if av == bv {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func TestMapEach(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
count := 0
m.Each(func(key interface{}, value interface{}) {
count++
if actualValue, expectedValue := count, value; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
switch value {
case 1:
if actualValue, expectedValue := key, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := key, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 3:
if actualValue, expectedValue := key, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
})
}
func TestMapMap(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
mappedMap := m.Map(func(key1 interface{}, value1 interface{}) (key2 interface{}, value2 interface{}) {
return key1, value1.(int) * value1.(int)
})
if actualValue, _ := mappedMap.Get("a"); actualValue != 1 {
t.Errorf("Got %v expected %v", actualValue, "mapped: a")
}
if actualValue, _ := mappedMap.Get("b"); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, "mapped: b")
}
if actualValue, _ := mappedMap.Get("c"); actualValue != 9 {
t.Errorf("Got %v expected %v", actualValue, "mapped: c")
}
if mappedMap.Size() != 3 {
t.Errorf("Got %v expected %v", mappedMap.Size(), 3)
}
}
func TestMapSelect(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
selectedMap := m.Select(func(key interface{}, value interface{}) bool {
return key.(string) >= "a" && key.(string) <= "b"
})
if actualValue, _ := selectedMap.Get("a"); actualValue != 1 {
t.Errorf("Got %v expected %v", actualValue, "value: a")
}
if actualValue, _ := selectedMap.Get("b"); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, "value: b")
}
if selectedMap.Size() != 2 {
t.Errorf("Got %v expected %v", selectedMap.Size(), 2)
}
}
func TestMapAny(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
any := m.Any(func(key interface{}, value interface{}) bool {
return value.(int) == 3
})
if any != true {
t.Errorf("Got %v expected %v", any, true)
}
any = m.Any(func(key interface{}, value interface{}) bool {
return value.(int) == 4
})
if any != false {
t.Errorf("Got %v expected %v", any, false)
}
}
func TestMapAll(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
all := m.All(func(key interface{}, value interface{}) bool {
return key.(string) >= "a" && key.(string) <= "c"
})
if all != true {
t.Errorf("Got %v expected %v", all, true)
}
all = m.All(func(key interface{}, value interface{}) bool {
return key.(string) >= "a" && key.(string) <= "b"
})
if all != false {
t.Errorf("Got %v expected %v", all, false)
}
}
func TestMapFind(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool {
return key.(string) == "c"
})
if foundKey != "c" || foundValue != 3 {
t.Errorf("Got %v -> %v expected %v -> %v", foundKey, foundValue, "c", 3)
}
foundKey, foundValue = m.Find(func(key interface{}, value interface{}) bool {
return key.(string) == "x"
})
if foundKey != nil || foundValue != nil {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundKey, nil, nil)
}
}
func TestMapChaining(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
chainedMap := m.Select(func(key interface{}, value interface{}) bool {
return value.(int) > 1
}).Map(func(key interface{}, value interface{}) (interface{}, interface{}) {
return key.(string) + key.(string), value.(int) * value.(int)
})
if actualValue := chainedMap.Size(); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, found := chainedMap.Get("aa"); actualValue != nil || found {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue, found := chainedMap.Get("bb"); actualValue != 4 || !found {
t.Errorf("Got %v expected %v", actualValue, 4)
}
if actualValue, found := chainedMap.Get("cc"); actualValue != 9 || !found {
t.Errorf("Got %v expected %v", actualValue, 9)
}
}
func TestMapIteratorNextOnEmpty(t *testing.T) {
m := NewWithStringComparators()
it := m.Iterator()
it = m.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty map")
}
}
func TestMapIteratorPrevOnEmpty(t *testing.T) {
m := NewWithStringComparators()
it := m.Iterator()
it = m.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty map")
}
}
func TestMapIteratorNext(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
it := m.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
value := it.Value()
switch key {
case "a":
if actualValue, expectedValue := value, 1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "b":
if actualValue, expectedValue := value, 2; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "c":
if actualValue, expectedValue := value, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestMapIteratorPrev(t *testing.T) {
m := NewWith(utils.StringComparator, utils.IntComparator)
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
it := m.Iterator()
for it.Next() {
}
countDown := m.Size()
for it.Prev() {
key := it.Key()
value := it.Value()
switch key {
case "a":
if actualValue, expectedValue := value, 1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "b":
if actualValue, expectedValue := value, 2; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "c":
if actualValue, expectedValue := value, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := value, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestMapIteratorBegin(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
it := m.Iterator()
it.Begin()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
for it.Next() {
}
it.Begin()
it.Next()
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestMapTreeIteratorEnd(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
it := m.Iterator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it.End()
it.Prev()
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestMapIteratorFirst(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it := m.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestMapIteratorLast(t *testing.T) {
m := NewWith(utils.IntComparator, utils.StringComparator)
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it := m.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestMapSerialization(t *testing.T) {
m := NewWithStringComparators()
m.Put("a", "1")
m.Put("b", "2")
m.Put("c", "3")
var err error
assert := func() {
if actualValue := m.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" {
t.Errorf("Got %v expected %v", actualValue, "[a,b,c]")
}
if actualValue := m.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := m.ToJSON()
assert()
err = m.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Get(n)
}
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, n)
}
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkTreeBidiMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeBidiMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparators()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeBidiMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeBidiMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeBidiMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeBidiMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparators()
for n := 0; n < size; n++ {
m.Put(n, n)
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

View file

@ -0,0 +1,83 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treemap
import (
"github.com/emirpasic/gods/containers"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
func assertEnumerableImplementation() {
var _ containers.EnumerableWithKey = (*Map)(nil)
}
// Each calls the given function once for each element, passing that element's key and value.
func (m *Map) Each(f func(key interface{}, value interface{})) {
iterator := m.Iterator()
for iterator.Next() {
f(iterator.Key(), iterator.Value())
}
}
// Map invokes the given function once for each element and returns a container
// containing the values returned by the given function as key/value pairs.
func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, interface{})) *Map {
newMap := &Map{tree: rbt.NewWith(m.tree.Comparator)}
iterator := m.Iterator()
for iterator.Next() {
key2, value2 := f(iterator.Key(), iterator.Value())
newMap.Put(key2, value2)
}
return newMap
}
// Select returns a new container containing all elements for which the given function returns a true value.
func (m *Map) Select(f func(key interface{}, value interface{}) bool) *Map {
newMap := &Map{tree: rbt.NewWith(m.tree.Comparator)}
iterator := m.Iterator()
for iterator.Next() {
if f(iterator.Key(), iterator.Value()) {
newMap.Put(iterator.Key(), iterator.Value())
}
}
return newMap
}
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
func (m *Map) Any(f func(key interface{}, value interface{}) bool) bool {
iterator := m.Iterator()
for iterator.Next() {
if f(iterator.Key(), iterator.Value()) {
return true
}
}
return false
}
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
func (m *Map) All(f func(key interface{}, value interface{}) bool) bool {
iterator := m.Iterator()
for iterator.Next() {
if !f(iterator.Key(), iterator.Value()) {
return false
}
}
return true
}
// Find passes each element of the container to the given function and returns
// the first (key,value) for which the function is true or nil,nil otherwise if no element
// matches the criteria.
func (m *Map) Find(f func(key interface{}, value interface{}) bool) (interface{}, interface{}) {
iterator := m.Iterator()
for iterator.Next() {
if f(iterator.Key(), iterator.Value()) {
return iterator.Key(), iterator.Value()
}
}
return nil, nil
}

View file

@ -0,0 +1,77 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treemap
import (
"github.com/emirpasic/gods/containers"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
iterator rbt.Iterator
}
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (m *Map) Iterator() Iterator {
return Iterator{iterator: m.tree.Iterator()}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
return iterator.iterator.Next()
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
return iterator.iterator.Prev()
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.iterator.Value()
}
// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} {
return iterator.iterator.Key()
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.iterator.Begin()
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.iterator.End()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
return iterator.iterator.First()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
return iterator.iterator.Last()
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treemap
import "github.com/emirpasic/gods/containers"
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Map)(nil)
var _ containers.JSONDeserializer = (*Map)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (m *Map) ToJSON() ([]byte, error) {
return m.tree.ToJSON()
}
// FromJSON populates list's elements from the input JSON representation.
func (m *Map) FromJSON(data []byte) error {
return m.tree.FromJSON(data)
}

View file

@ -0,0 +1,117 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package treemap implements a map backed by red-black tree.
//
// Elements are ordered by key in the map.
//
// Structure is not thread safe.
//
// Reference: http://en.wikipedia.org/wiki/Associative_array
package treemap
import (
"fmt"
"github.com/emirpasic/gods/maps"
rbt "github.com/emirpasic/gods/trees/redblacktree"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertMapImplementation() {
var _ maps.Map = (*Map)(nil)
}
// Map holds the elements in a red-black tree
type Map struct {
tree *rbt.Tree
}
// NewWith instantiates a tree map with the custom comparator.
func NewWith(comparator utils.Comparator) *Map {
return &Map{tree: rbt.NewWith(comparator)}
}
// NewWithIntComparator instantiates a tree map with the IntComparator, i.e. keys are of type int.
func NewWithIntComparator() *Map {
return &Map{tree: rbt.NewWithIntComparator()}
}
// NewWithStringComparator instantiates a tree map with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator() *Map {
return &Map{tree: rbt.NewWithStringComparator()}
}
// Put inserts key-value pair into the map.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (m *Map) Put(key interface{}, value interface{}) {
m.tree.Put(key, value)
}
// Get searches the element in the map by key and returns its value or nil if key is not found in tree.
// Second return parameter is true if key was found, otherwise false.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (m *Map) Get(key interface{}) (value interface{}, found bool) {
return m.tree.Get(key)
}
// Remove removes the element from the map by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (m *Map) Remove(key interface{}) {
m.tree.Remove(key)
}
// Empty returns true if map does not contain any elements
func (m *Map) Empty() bool {
return m.tree.Empty()
}
// Size returns number of elements in the map.
func (m *Map) Size() int {
return m.tree.Size()
}
// Keys returns all keys in-order
func (m *Map) Keys() []interface{} {
return m.tree.Keys()
}
// Values returns all values in-order based on the key.
func (m *Map) Values() []interface{} {
return m.tree.Values()
}
// Clear removes all elements from the map.
func (m *Map) Clear() {
m.tree.Clear()
}
// Min returns the minimum key and its value from the tree map.
// Returns nil, nil if map is empty.
func (m *Map) Min() (key interface{}, value interface{}) {
if node := m.tree.Left(); node != nil {
return node.Key, node.Value
}
return nil, nil
}
// Max returns the maximum key and its value from the tree map.
// Returns nil, nil if map is empty.
func (m *Map) Max() (key interface{}, value interface{}) {
if node := m.tree.Right(); node != nil {
return node.Key, node.Value
}
return nil, nil
}
// String returns a string representation of container
func (m *Map) String() string {
str := "TreeMap\nmap["
it := m.Iterator()
for it.Next() {
str += fmt.Sprintf("%v:%v ", it.Key(), it.Value())
}
return strings.TrimRight(str, " ") + "]"
}

View file

@ -0,0 +1,625 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treemap
import (
"fmt"
"testing"
)
func TestMapPut(t *testing.T) {
m := NewWithIntComparator()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
if actualValue := m.Size(); actualValue != 7 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// key,expectedValue,expectedFound
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
}
func TestMapRemove(t *testing.T) {
m := NewWithIntComparator()
m.Put(5, "e")
m.Put(6, "f")
m.Put(7, "g")
m.Put(3, "c")
m.Put(4, "d")
m.Put(1, "x")
m.Put(2, "b")
m.Put(1, "a") //overwrite
m.Remove(5)
m.Remove(6)
m.Remove(7)
m.Remove(8)
m.Remove(5)
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 4)
}
tests2 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
}
for _, test := range tests2 {
actualValue, actualFound := m.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
m.Remove(1)
m.Remove(4)
m.Remove(2)
m.Remove(3)
m.Remove(2)
m.Remove(2)
if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := m.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
if actualValue := m.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
}
func sameElements(a []interface{}, b []interface{}) bool {
if len(a) != len(b) {
return false
}
for _, av := range a {
found := false
for _, bv := range b {
if av == bv {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func TestMapEach(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
count := 0
m.Each(func(key interface{}, value interface{}) {
count++
if actualValue, expectedValue := count, value; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
switch value {
case 1:
if actualValue, expectedValue := key, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := key, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 3:
if actualValue, expectedValue := key, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
})
}
func TestMapMap(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
mappedMap := m.Map(func(key1 interface{}, value1 interface{}) (key2 interface{}, value2 interface{}) {
return key1, value1.(int) * value1.(int)
})
if actualValue, _ := mappedMap.Get("a"); actualValue != 1 {
t.Errorf("Got %v expected %v", actualValue, "mapped: a")
}
if actualValue, _ := mappedMap.Get("b"); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, "mapped: b")
}
if actualValue, _ := mappedMap.Get("c"); actualValue != 9 {
t.Errorf("Got %v expected %v", actualValue, "mapped: c")
}
if mappedMap.Size() != 3 {
t.Errorf("Got %v expected %v", mappedMap.Size(), 3)
}
}
func TestMapSelect(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
selectedMap := m.Select(func(key interface{}, value interface{}) bool {
return key.(string) >= "a" && key.(string) <= "b"
})
if actualValue, _ := selectedMap.Get("a"); actualValue != 1 {
t.Errorf("Got %v expected %v", actualValue, "value: a")
}
if actualValue, _ := selectedMap.Get("b"); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, "value: b")
}
if selectedMap.Size() != 2 {
t.Errorf("Got %v expected %v", selectedMap.Size(), 2)
}
}
func TestMapAny(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
any := m.Any(func(key interface{}, value interface{}) bool {
return value.(int) == 3
})
if any != true {
t.Errorf("Got %v expected %v", any, true)
}
any = m.Any(func(key interface{}, value interface{}) bool {
return value.(int) == 4
})
if any != false {
t.Errorf("Got %v expected %v", any, false)
}
}
func TestMapAll(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
all := m.All(func(key interface{}, value interface{}) bool {
return key.(string) >= "a" && key.(string) <= "c"
})
if all != true {
t.Errorf("Got %v expected %v", all, true)
}
all = m.All(func(key interface{}, value interface{}) bool {
return key.(string) >= "a" && key.(string) <= "b"
})
if all != false {
t.Errorf("Got %v expected %v", all, false)
}
}
func TestMapFind(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool {
return key.(string) == "c"
})
if foundKey != "c" || foundValue != 3 {
t.Errorf("Got %v -> %v expected %v -> %v", foundKey, foundValue, "c", 3)
}
foundKey, foundValue = m.Find(func(key interface{}, value interface{}) bool {
return key.(string) == "x"
})
if foundKey != nil || foundValue != nil {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundKey, nil, nil)
}
}
func TestMapChaining(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
chainedMap := m.Select(func(key interface{}, value interface{}) bool {
return value.(int) > 1
}).Map(func(key interface{}, value interface{}) (interface{}, interface{}) {
return key.(string) + key.(string), value.(int) * value.(int)
})
if actualValue := chainedMap.Size(); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, found := chainedMap.Get("aa"); actualValue != nil || found {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue, found := chainedMap.Get("bb"); actualValue != 4 || !found {
t.Errorf("Got %v expected %v", actualValue, 4)
}
if actualValue, found := chainedMap.Get("cc"); actualValue != 9 || !found {
t.Errorf("Got %v expected %v", actualValue, 9)
}
}
func TestMapIteratorNextOnEmpty(t *testing.T) {
m := NewWithStringComparator()
it := m.Iterator()
it = m.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty map")
}
}
func TestMapIteratorPrevOnEmpty(t *testing.T) {
m := NewWithStringComparator()
it := m.Iterator()
it = m.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty map")
}
}
func TestMapIteratorNext(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
it := m.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
value := it.Value()
switch key {
case "a":
if actualValue, expectedValue := value, 1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "b":
if actualValue, expectedValue := value, 2; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "c":
if actualValue, expectedValue := value, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestMapIteratorPrev(t *testing.T) {
m := NewWithStringComparator()
m.Put("c", 3)
m.Put("a", 1)
m.Put("b", 2)
it := m.Iterator()
for it.Next() {
}
countDown := m.Size()
for it.Prev() {
key := it.Key()
value := it.Value()
switch key {
case "a":
if actualValue, expectedValue := value, 1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "b":
if actualValue, expectedValue := value, 2; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case "c":
if actualValue, expectedValue := value, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := value, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestMapIteratorBegin(t *testing.T) {
m := NewWithIntComparator()
it := m.Iterator()
it.Begin()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
for it.Next() {
}
it.Begin()
it.Next()
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestMapTreeIteratorEnd(t *testing.T) {
m := NewWithIntComparator()
it := m.Iterator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it.End()
it.Prev()
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestMapIteratorFirst(t *testing.T) {
m := NewWithIntComparator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it := m.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestMapIteratorLast(t *testing.T) {
m := NewWithIntComparator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it := m.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestMapSerialization(t *testing.T) {
m := NewWithStringComparator()
m.Put("a", "1")
m.Put("b", "2")
m.Put("c", "3")
var err error
assert := func() {
if actualValue := m.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" {
t.Errorf("Got %v expected %v", actualValue, "[a,b,c]")
}
if actualValue := m.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := m.ToJSON()
assert()
err = m.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Get(n)
}
}
}
func benchmarkPut(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, m *Map, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
m.Remove(n)
}
}
}
func BenchmarkTreeMapGet100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapGet1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapGet10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapGet100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, m, size)
}
func BenchmarkTreeMapPut100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparator()
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapPut1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapPut10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapPut100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, m, size)
}
func BenchmarkTreeMapRemove100(b *testing.B) {
b.StopTimer()
size := 100
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeMapRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeMapRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}
func BenchmarkTreeMapRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
m := NewWithIntComparator()
for n := 0; n < size; n++ {
m.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, m, size)
}

View file

@ -0,0 +1,95 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package hashset implements a set backed by a hash table.
//
// Structure is not thread safe.
//
// References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29
package hashset
import (
"fmt"
"github.com/emirpasic/gods/sets"
"strings"
)
func assertSetImplementation() {
var _ sets.Set = (*Set)(nil)
}
// Set holds elements in go's native map
type Set struct {
items map[interface{}]struct{}
}
var itemExists = struct{}{}
// New instantiates a new empty set
func New() *Set {
return &Set{items: make(map[interface{}]struct{})}
}
// Add adds the items (one or more) to the set.
func (set *Set) Add(items ...interface{}) {
for _, item := range items {
set.items[item] = itemExists
}
}
// Remove removes the items (one or more) from the set.
func (set *Set) Remove(items ...interface{}) {
for _, item := range items {
delete(set.items, item)
}
}
// Contains check if items (one or more) are present in the set.
// All items have to be present in the set for the method to return true.
// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.
func (set *Set) Contains(items ...interface{}) bool {
for _, item := range items {
if _, contains := set.items[item]; !contains {
return false
}
}
return true
}
// Empty returns true if set does not contain any elements.
func (set *Set) Empty() bool {
return set.Size() == 0
}
// Size returns number of elements within the set.
func (set *Set) Size() int {
return len(set.items)
}
// Clear clears all values in the set.
func (set *Set) Clear() {
set.items = make(map[interface{}]struct{})
}
// Values returns all items in the set.
func (set *Set) Values() []interface{} {
values := make([]interface{}, set.Size())
count := 0
for item := range set.items {
values[count] = item
count++
}
return values
}
// String returns a string representation of container
func (set *Set) String() string {
str := "HashSet\n"
items := []string{}
for k := range set.items {
items = append(items, fmt.Sprintf("%v", k))
}
str += strings.Join(items, ", ")
return str
}

View file

@ -0,0 +1,242 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package hashset
import (
"testing"
)
func TestSetAdd(t *testing.T) {
set := New()
set.Add()
set.Add(1)
set.Add(2)
set.Add(2, 3)
set.Add()
if actualValue := set.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := set.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
}
func TestSetContains(t *testing.T) {
set := New()
set.Add(3, 1, 2)
set.Add(2, 3)
set.Add()
if actualValue := set.Contains(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := set.Contains(1); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := set.Contains(1, 2, 3); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := set.Contains(1, 2, 3, 4); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
}
func TestSetRemove(t *testing.T) {
set := New()
set.Add(3, 1, 2)
set.Remove()
if actualValue := set.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
set.Remove(1)
if actualValue := set.Size(); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, 2)
}
set.Remove(3)
set.Remove(3)
set.Remove()
set.Remove(2)
if actualValue := set.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestSetSerialization(t *testing.T) {
set := New()
set.Add("a", "b", "c")
var err error
assert := func() {
if actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := set.Contains("a", "b", "c"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := set.ToJSON()
assert()
err = set.FromJSON(json)
assert()
}
func benchmarkContains(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Contains(n)
}
}
}
func benchmarkAdd(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Remove(n)
}
}
}
func BenchmarkHashSetContains100(b *testing.B) {
b.StopTimer()
size := 100
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetContains1000(b *testing.B) {
b.StopTimer()
size := 1000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetContains10000(b *testing.B) {
b.StopTimer()
size := 10000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetContains100000(b *testing.B) {
b.StopTimer()
size := 100000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkHashSetAdd100(b *testing.B) {
b.StopTimer()
size := 100
set := New()
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkHashSetRemove100(b *testing.B) {
b.StopTimer()
size := 100
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkHashSetRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkHashSetRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkHashSetRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
set := New()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package hashset
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Set)(nil)
var _ containers.JSONDeserializer = (*Set)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (set *Set) ToJSON() ([]byte, error) {
return json.Marshal(set.Values())
}
// FromJSON populates list's elements from the input JSON representation.
func (set *Set) FromJSON(data []byte) error {
elements := []interface{}{}
err := json.Unmarshal(data, &elements)
if err == nil {
set.Clear()
set.Add(elements...)
}
return err
}

25
vendor/github.com/emirpasic/gods/sets/sets.go generated vendored Normal file
View file

@ -0,0 +1,25 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package sets provides an abstract Set interface.
//
// In computer science, a set is an abstract data type that can store certain values and no repeated values. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests a value for membership in a set.
//
// Reference: https://en.wikipedia.org/wiki/Set_%28abstract_data_type%29
package sets
import "github.com/emirpasic/gods/containers"
// Set interface that all sets implement
type Set interface {
Add(elements ...interface{})
Remove(elements ...interface{})
Contains(elements ...interface{}) bool
containers.Container
// Empty() bool
// Size() int
// Clear()
// Values() []interface{}
}

View file

@ -0,0 +1,82 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treeset
import (
"github.com/emirpasic/gods/containers"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
func assertEnumerableImplementation() {
var _ containers.EnumerableWithIndex = (*Set)(nil)
}
// Each calls the given function once for each element, passing that element's index and value.
func (set *Set) Each(f func(index int, value interface{})) {
iterator := set.Iterator()
for iterator.Next() {
f(iterator.Index(), iterator.Value())
}
}
// Map invokes the given function once for each element and returns a
// container containing the values returned by the given function.
func (set *Set) Map(f func(index int, value interface{}) interface{}) *Set {
newSet := &Set{tree: rbt.NewWith(set.tree.Comparator)}
iterator := set.Iterator()
for iterator.Next() {
newSet.Add(f(iterator.Index(), iterator.Value()))
}
return newSet
}
// Select returns a new container containing all elements for which the given function returns a true value.
func (set *Set) Select(f func(index int, value interface{}) bool) *Set {
newSet := &Set{tree: rbt.NewWith(set.tree.Comparator)}
iterator := set.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
newSet.Add(iterator.Value())
}
}
return newSet
}
// Any passes each element of the container to the given function and
// returns true if the function ever returns true for any element.
func (set *Set) Any(f func(index int, value interface{}) bool) bool {
iterator := set.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return true
}
}
return false
}
// All passes each element of the container to the given function and
// returns true if the function returns true for all elements.
func (set *Set) All(f func(index int, value interface{}) bool) bool {
iterator := set.Iterator()
for iterator.Next() {
if !f(iterator.Index(), iterator.Value()) {
return false
}
}
return true
}
// Find passes each element of the container to the given function and returns
// the first (index,value) for which the function is true or -1,nil otherwise
// if no element matches the criteria.
func (set *Set) Find(f func(index int, value interface{}) bool) (int, interface{}) {
iterator := set.Iterator()
for iterator.Next() {
if f(iterator.Index(), iterator.Value()) {
return iterator.Index(), iterator.Value()
}
}
return -1, nil
}

View file

@ -0,0 +1,89 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treeset
import (
"github.com/emirpasic/gods/containers"
rbt "github.com/emirpasic/gods/trees/redblacktree"
)
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
type Iterator struct {
index int
iterator rbt.Iterator
tree *rbt.Tree
}
// Iterator holding the iterator's state
func (set *Set) Iterator() Iterator {
return Iterator{index: -1, iterator: set.tree.Iterator(), tree: set.tree}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.tree.Size() {
iterator.index++
}
return iterator.iterator.Next()
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
return iterator.iterator.Prev()
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.iterator.Key()
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
iterator.iterator.Begin()
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.tree.Size()
iterator.iterator.End()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.iterator.Last()
}

View file

@ -0,0 +1,31 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treeset
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Set)(nil)
var _ containers.JSONDeserializer = (*Set)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (set *Set) ToJSON() ([]byte, error) {
return json.Marshal(set.Values())
}
// FromJSON populates list's elements from the input JSON representation.
func (set *Set) FromJSON(data []byte) error {
elements := []interface{}{}
err := json.Unmarshal(data, &elements)
if err == nil {
set.Clear()
set.Add(elements...)
}
return err
}

View file

@ -0,0 +1,101 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package treeset implements a tree backed by a red-black tree.
//
// Structure is not thread safe.
//
// Reference: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29
package treeset
import (
"fmt"
"github.com/emirpasic/gods/sets"
rbt "github.com/emirpasic/gods/trees/redblacktree"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertSetImplementation() {
var _ sets.Set = (*Set)(nil)
}
// Set holds elements in a red-black tree
type Set struct {
tree *rbt.Tree
}
var itemExists = struct{}{}
// NewWith instantiates a new empty set with the custom comparator.
func NewWith(comparator utils.Comparator) *Set {
return &Set{tree: rbt.NewWith(comparator)}
}
// NewWithIntComparator instantiates a new empty set with the IntComparator, i.e. keys are of type int.
func NewWithIntComparator() *Set {
return &Set{tree: rbt.NewWithIntComparator()}
}
// NewWithStringComparator instantiates a new empty set with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator() *Set {
return &Set{tree: rbt.NewWithStringComparator()}
}
// Add adds the items (one or more) to the set.
func (set *Set) Add(items ...interface{}) {
for _, item := range items {
set.tree.Put(item, itemExists)
}
}
// Remove removes the items (one or more) from the set.
func (set *Set) Remove(items ...interface{}) {
for _, item := range items {
set.tree.Remove(item)
}
}
// Contains checks weather items (one or more) are present in the set.
// All items have to be present in the set for the method to return true.
// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.
func (set *Set) Contains(items ...interface{}) bool {
for _, item := range items {
if _, contains := set.tree.Get(item); !contains {
return false
}
}
return true
}
// Empty returns true if set does not contain any elements.
func (set *Set) Empty() bool {
return set.tree.Size() == 0
}
// Size returns number of elements within the set.
func (set *Set) Size() int {
return set.tree.Size()
}
// Clear clears all values in the set.
func (set *Set) Clear() {
set.tree.Clear()
}
// Values returns all items in the set.
func (set *Set) Values() []interface{} {
return set.tree.Keys()
}
// String returns a string representation of container
func (set *Set) String() string {
str := "TreeSet\n"
items := []string{}
for _, v := range set.tree.Keys() {
items = append(items, fmt.Sprintf("%v", v))
}
str += strings.Join(items, ", ")
return str
}

View file

@ -0,0 +1,507 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package treeset
import (
"fmt"
"testing"
)
func TestSetAdd(t *testing.T) {
set := NewWithIntComparator()
set.Add()
set.Add(1)
set.Add(2)
set.Add(2, 3)
set.Add()
if actualValue := set.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := set.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, expectedValue := fmt.Sprintf("%d%d%d", set.Values()...), "123"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestSetContains(t *testing.T) {
set := NewWithIntComparator()
set.Add(3, 1, 2)
if actualValue := set.Contains(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := set.Contains(1); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := set.Contains(1, 2, 3); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := set.Contains(1, 2, 3, 4); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
}
func TestSetRemove(t *testing.T) {
set := NewWithIntComparator()
set.Add(3, 1, 2)
set.Remove()
if actualValue := set.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
set.Remove(1)
if actualValue := set.Size(); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, 2)
}
set.Remove(3)
set.Remove(3)
set.Remove()
set.Remove(2)
if actualValue := set.Size(); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}
func TestSetEach(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
set.Each(func(index int, value interface{}) {
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
})
}
func TestSetMap(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
mappedSet := set.Map(func(index int, value interface{}) interface{} {
return "mapped: " + value.(string)
})
if actualValue, expectedValue := mappedSet.Contains("mapped: a", "mapped: b", "mapped: c"), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := mappedSet.Contains("mapped: a", "mapped: b", "mapped: x"), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if mappedSet.Size() != 3 {
t.Errorf("Got %v expected %v", mappedSet.Size(), 3)
}
}
func TestSetSelect(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
selectedSet := set.Select(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if actualValue, expectedValue := selectedSet.Contains("a", "b"), true; actualValue != expectedValue {
fmt.Println("A: ", selectedSet.Contains("b"))
t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]")
}
if actualValue, expectedValue := selectedSet.Contains("a", "b", "c"), false; actualValue != expectedValue {
t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]")
}
if selectedSet.Size() != 2 {
t.Errorf("Got %v expected %v", selectedSet.Size(), 3)
}
}
func TestSetAny(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
any := set.Any(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if any != true {
t.Errorf("Got %v expected %v", any, true)
}
any = set.Any(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if any != false {
t.Errorf("Got %v expected %v", any, false)
}
}
func TestSetAll(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
all := set.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "c"
})
if all != true {
t.Errorf("Got %v expected %v", all, true)
}
all = set.All(func(index int, value interface{}) bool {
return value.(string) >= "a" && value.(string) <= "b"
})
if all != false {
t.Errorf("Got %v expected %v", all, false)
}
}
func TestSetFind(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
foundIndex, foundValue := set.Find(func(index int, value interface{}) bool {
return value.(string) == "c"
})
if foundValue != "c" || foundIndex != 2 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2)
}
foundIndex, foundValue = set.Find(func(index int, value interface{}) bool {
return value.(string) == "x"
})
if foundValue != nil || foundIndex != -1 {
t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil)
}
}
func TestSetChaining(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
}
func TestSetIteratorNextOnEmpty(t *testing.T) {
set := NewWithStringComparator()
it := set.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty set")
}
}
func TestSetIteratorPrevOnEmpty(t *testing.T) {
set := NewWithStringComparator()
it := set.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty set")
}
}
func TestSetIteratorNext(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
it := set.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestSetIteratorPrev(t *testing.T) {
set := NewWithStringComparator()
set.Add("c", "a", "b")
it := set.Iterator()
for it.Prev() {
}
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestSetIteratorBegin(t *testing.T) {
m := NewWithStringComparator()
it := m.Iterator()
it.Begin()
m.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestSetIteratorEnd(t *testing.T) {
set := NewWithStringComparator()
it := set.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
set.Add("a", "b", "c")
it.End()
if index := it.Index(); index != set.Size() {
t.Errorf("Got %v expected %v", index, set.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != set.Size()-1 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, set.Size()-1, "c")
}
}
func TestSetIteratorFirst(t *testing.T) {
set := NewWithStringComparator()
set.Add("a", "b", "c")
it := set.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestSetIteratorLast(t *testing.T) {
set := NewWithStringComparator()
set.Add("a", "b", "c")
it := set.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 3, "c")
}
}
func TestSetSerialization(t *testing.T) {
set := NewWithStringComparator()
set.Add("a", "b", "c")
var err error
assert := func() {
if actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := set.Contains("a", "b", "c"); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := set.ToJSON()
assert()
err = set.FromJSON(json)
assert()
}
func benchmarkContains(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Contains(n)
}
}
}
func benchmarkAdd(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Add(n)
}
}
}
func benchmarkRemove(b *testing.B, set *Set, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
set.Remove(n)
}
}
}
func BenchmarkTreeSetContains100(b *testing.B) {
b.StopTimer()
size := 100
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetContains1000(b *testing.B) {
b.StopTimer()
size := 1000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetContains10000(b *testing.B) {
b.StopTimer()
size := 10000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetContains100000(b *testing.B) {
b.StopTimer()
size := 100000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkContains(b, set, size)
}
func BenchmarkTreeSetAdd100(b *testing.B) {
b.StopTimer()
size := 100
set := NewWithIntComparator()
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetAdd1000(b *testing.B) {
b.StopTimer()
size := 1000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetAdd10000(b *testing.B) {
b.StopTimer()
size := 10000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetAdd100000(b *testing.B) {
b.StopTimer()
size := 100000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkAdd(b, set, size)
}
func BenchmarkTreeSetRemove100(b *testing.B) {
b.StopTimer()
size := 100
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkTreeSetRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkTreeSetRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}
func BenchmarkTreeSetRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
set := NewWithIntComparator()
for n := 0; n < size; n++ {
set.Add(n)
}
b.StartTimer()
benchmarkRemove(b, set, size)
}

View file

@ -0,0 +1,91 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package arraystack implements a stack backed by array list.
//
// Structure is not thread safe.
//
// Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Array
package arraystack
import (
"fmt"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/stacks"
"strings"
)
func assertStackImplementation() {
var _ stacks.Stack = (*Stack)(nil)
}
// Stack holds elements in an array-list
type Stack struct {
list *arraylist.List
}
// New instantiates a new empty stack
func New() *Stack {
return &Stack{list: arraylist.New()}
}
// Push adds a value onto the top of the stack
func (stack *Stack) Push(value interface{}) {
stack.list.Add(value)
}
// Pop removes top element on stack and returns it, or nil if stack is empty.
// Second return parameter is true, unless the stack was empty and there was nothing to pop.
func (stack *Stack) Pop() (value interface{}, ok bool) {
value, ok = stack.list.Get(stack.list.Size() - 1)
stack.list.Remove(stack.list.Size() - 1)
return
}
// Peek returns top element on the stack without removing it, or nil if stack is empty.
// Second return parameter is true, unless the stack was empty and there was nothing to peek.
func (stack *Stack) Peek() (value interface{}, ok bool) {
return stack.list.Get(stack.list.Size() - 1)
}
// Empty returns true if stack does not contain any elements.
func (stack *Stack) Empty() bool {
return stack.list.Empty()
}
// Size returns number of elements within the stack.
func (stack *Stack) Size() int {
return stack.list.Size()
}
// Clear removes all elements from the stack.
func (stack *Stack) Clear() {
stack.list.Clear()
}
// Values returns all elements in the stack (LIFO order).
func (stack *Stack) Values() []interface{} {
size := stack.list.Size()
elements := make([]interface{}, size, size)
for i := 1; i <= size; i++ {
elements[size-i], _ = stack.list.Get(i - 1) // in reverse (LIFO)
}
return elements
}
// String returns a string representation of container
func (stack *Stack) String() string {
str := "ArrayStack\n"
values := []string{}
for _, value := range stack.list.Values() {
values = append(values, fmt.Sprintf("%v", value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (stack *Stack) withinRange(index int) bool {
return index >= 0 && index < stack.list.Size()
}

View file

@ -0,0 +1,362 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraystack
import (
"fmt"
"testing"
)
func TestStackPush(t *testing.T) {
stack := New()
if actualValue := stack.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
stack.Push(1)
stack.Push(2)
stack.Push(3)
if actualValue := stack.Values(); actualValue[0].(int) != 3 || actualValue[1].(int) != 2 || actualValue[2].(int) != 1 {
t.Errorf("Got %v expected %v", actualValue, "[3,2,1]")
}
if actualValue := stack.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := stack.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := stack.Peek(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
}
func TestStackPeek(t *testing.T) {
stack := New()
if actualValue, ok := stack.Peek(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
stack.Push(1)
stack.Push(2)
stack.Push(3)
if actualValue, ok := stack.Peek(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
}
func TestStackPop(t *testing.T) {
stack := New()
stack.Push(1)
stack.Push(2)
stack.Push(3)
stack.Pop()
if actualValue, ok := stack.Peek(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := stack.Pop(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := stack.Pop(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
if actualValue, ok := stack.Pop(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := stack.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := stack.Values(); len(actualValue) != 0 {
t.Errorf("Got %v expected %v", actualValue, "[]")
}
}
func TestStackIteratorOnEmpty(t *testing.T) {
stack := New()
it := stack.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty stack")
}
}
func TestStackIteratorNext(t *testing.T) {
stack := New()
stack.Push("a")
stack.Push("b")
stack.Push("c")
it := stack.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestStackIteratorPrev(t *testing.T) {
stack := New()
stack.Push("a")
stack.Push("b")
stack.Push("c")
it := stack.Iterator()
for it.Next() {
}
count := 0
for it.Prev() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, 3-count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestStackIteratorBegin(t *testing.T) {
stack := New()
it := stack.Iterator()
it.Begin()
stack.Push("a")
stack.Push("b")
stack.Push("c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackIteratorEnd(t *testing.T) {
stack := New()
it := stack.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
it.End()
if index := it.Index(); index != stack.Size() {
t.Errorf("Got %v expected %v", index, stack.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != stack.Size()-1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, stack.Size()-1, "a")
}
}
func TestStackIteratorFirst(t *testing.T) {
stack := New()
it := stack.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackIteratorLast(t *testing.T) {
stack := New()
it := stack.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "a")
}
}
func TestStackSerialization(t *testing.T) {
stack := New()
stack.Push("a")
stack.Push("b")
stack.Push("c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", stack.Values()...), "cba"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := stack.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := stack.ToJSON()
assert()
err = stack.FromJSON(json)
assert()
}
func benchmarkPush(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
stack.Push(n)
}
}
}
func benchmarkPop(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
stack.Pop()
}
}
}
func BenchmarkArrayStackPop100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPop1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPop10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPop100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkArrayStackPush100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkArrayStackPush1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkArrayStackPush10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkArrayStackPush100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}

View file

@ -0,0 +1,84 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraystack
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
type Iterator struct {
stack *Stack
index int
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (stack *Stack) Iterator() Iterator {
return Iterator{stack: stack, index: -1}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.stack.Size() {
iterator.index++
}
return iterator.stack.withinRange(iterator.index)
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
return iterator.stack.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
value, _ := iterator.stack.list.Get(iterator.stack.list.Size() - iterator.index - 1) // in reverse (LIFO)
return value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.stack.Size()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package arraystack
import "github.com/emirpasic/gods/containers"
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Stack)(nil)
var _ containers.JSONDeserializer = (*Stack)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (stack *Stack) ToJSON() ([]byte, error) {
return stack.list.ToJSON()
}
// FromJSON populates list's elements from the input JSON representation.
func (stack *Stack) FromJSON(data []byte) error {
return stack.list.FromJSON(data)
}

View file

@ -0,0 +1,60 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linkedliststack
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.IteratorWithIndex = (*Iterator)(nil)
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
type Iterator struct {
stack *Stack
index int
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (stack *Stack) Iterator() Iterator {
return Iterator{stack: stack, index: -1}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.stack.Size() {
iterator.index++
}
return iterator.stack.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
value, _ := iterator.stack.list.Get(iterator.index) // in reverse (LIFO)
return value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}

View file

@ -0,0 +1,86 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package linkedliststack implements a stack backed by a singly-linked list.
//
// Structure is not thread safe.
//
// Reference:https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Linked_list
package linkedliststack
import (
"fmt"
"github.com/emirpasic/gods/lists/singlylinkedlist"
"github.com/emirpasic/gods/stacks"
"strings"
)
func assertStackImplementation() {
var _ stacks.Stack = (*Stack)(nil)
}
// Stack holds elements in a singly-linked-list
type Stack struct {
list *singlylinkedlist.List
}
// New nnstantiates a new empty stack
func New() *Stack {
return &Stack{list: &singlylinkedlist.List{}}
}
// Push adds a value onto the top of the stack
func (stack *Stack) Push(value interface{}) {
stack.list.Prepend(value)
}
// Pop removes top element on stack and returns it, or nil if stack is empty.
// Second return parameter is true, unless the stack was empty and there was nothing to pop.
func (stack *Stack) Pop() (value interface{}, ok bool) {
value, ok = stack.list.Get(0)
stack.list.Remove(0)
return
}
// Peek returns top element on the stack without removing it, or nil if stack is empty.
// Second return parameter is true, unless the stack was empty and there was nothing to peek.
func (stack *Stack) Peek() (value interface{}, ok bool) {
return stack.list.Get(0)
}
// Empty returns true if stack does not contain any elements.
func (stack *Stack) Empty() bool {
return stack.list.Empty()
}
// Size returns number of elements within the stack.
func (stack *Stack) Size() int {
return stack.list.Size()
}
// Clear removes all elements from the stack.
func (stack *Stack) Clear() {
stack.list.Clear()
}
// Values returns all elements in the stack (LIFO order).
func (stack *Stack) Values() []interface{} {
return stack.list.Values()
}
// String returns a string representation of container
func (stack *Stack) String() string {
str := "LinkedListStack\n"
values := []string{}
for _, value := range stack.list.Values() {
values = append(values, fmt.Sprintf("%v", value))
}
str += strings.Join(values, ", ")
return str
}
// Check that the index is within bounds of the list
func (stack *Stack) withinRange(index int) bool {
return index >= 0 && index < stack.list.Size()
}

View file

@ -0,0 +1,278 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linkedliststack
import (
"fmt"
"testing"
)
func TestStackPush(t *testing.T) {
stack := New()
if actualValue := stack.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
stack.Push(1)
stack.Push(2)
stack.Push(3)
if actualValue := stack.Values(); actualValue[0].(int) != 3 || actualValue[1].(int) != 2 || actualValue[2].(int) != 1 {
t.Errorf("Got %v expected %v", actualValue, "[3,2,1]")
}
if actualValue := stack.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := stack.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := stack.Peek(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
}
func TestStackPeek(t *testing.T) {
stack := New()
if actualValue, ok := stack.Peek(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
stack.Push(1)
stack.Push(2)
stack.Push(3)
if actualValue, ok := stack.Peek(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
}
func TestStackPop(t *testing.T) {
stack := New()
stack.Push(1)
stack.Push(2)
stack.Push(3)
stack.Pop()
if actualValue, ok := stack.Peek(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := stack.Pop(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := stack.Pop(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
if actualValue, ok := stack.Pop(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := stack.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := stack.Values(); len(actualValue) != 0 {
t.Errorf("Got %v expected %v", actualValue, "[]")
}
}
func TestStackIterator(t *testing.T) {
stack := New()
stack.Push("a")
stack.Push("b")
stack.Push("c")
// Iterator
it := stack.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, "c"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, "b"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Clear()
it = stack.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty stack")
}
}
func TestStackIteratorBegin(t *testing.T) {
stack := New()
it := stack.Iterator()
it.Begin()
stack.Push("a")
stack.Push("b")
stack.Push("c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackIteratorFirst(t *testing.T) {
stack := New()
it := stack.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackSerialization(t *testing.T) {
stack := New()
stack.Push("a")
stack.Push("b")
stack.Push("c")
var err error
assert := func() {
if actualValue, expectedValue := fmt.Sprintf("%s%s%s", stack.Values()...), "cba"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := stack.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := stack.ToJSON()
assert()
err = stack.FromJSON(json)
assert()
}
func benchmarkPush(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
stack.Push(n)
}
}
}
func benchmarkPop(b *testing.B, stack *Stack, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
stack.Pop()
}
}
}
func BenchmarkLinkedListStackPop100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPop1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPop10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPop100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPop(b, stack, size)
}
func BenchmarkLinkedListStackPush100(b *testing.B) {
b.StopTimer()
size := 100
stack := New()
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkLinkedListStackPush1000(b *testing.B) {
b.StopTimer()
size := 1000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkLinkedListStackPush10000(b *testing.B) {
b.StopTimer()
size := 10000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}
func BenchmarkLinkedListStackPush100000(b *testing.B) {
b.StopTimer()
size := 100000
stack := New()
for n := 0; n < size; n++ {
stack.Push(n)
}
b.StartTimer()
benchmarkPush(b, stack, size)
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package linkedliststack
import "github.com/emirpasic/gods/containers"
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Stack)(nil)
var _ containers.JSONDeserializer = (*Stack)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (stack *Stack) ToJSON() ([]byte, error) {
return stack.list.ToJSON()
}
// FromJSON populates list's elements from the input JSON representation.
func (stack *Stack) FromJSON(data []byte) error {
return stack.list.FromJSON(data)
}

25
vendor/github.com/emirpasic/gods/stacks/stacks.go generated vendored Normal file
View file

@ -0,0 +1,25 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package stacks provides an abstract Stack interface.
//
// In computer science, a stack is an abstract data type that serves as a collection of elements, with two principal operations: push, which adds an element to the collection, and pop, which removes the most recently added element that was not yet removed. The order in which elements come off a stack gives rise to its alternative name, LIFO (for last in, first out). Additionally, a peek operation may give access to the top without modifying the stack.
//
// Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29
package stacks
import "github.com/emirpasic/gods/containers"
// Stack interface that all stacks implement
type Stack interface {
Push(value interface{})
Pop() (value interface{}, ok bool)
Peek() (value interface{}, ok bool)
containers.Container
// Empty() bool
// Size() int
// Clear()
// Values() []interface{}
}

View file

@ -0,0 +1,449 @@
// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package avltree implements an AVL balanced binary tree.
//
// Structure is not thread safe.
//
// References: https://en.wikipedia.org/wiki/AVL_tree
package avltree
import (
"fmt"
"github.com/emirpasic/gods/trees"
"github.com/emirpasic/gods/utils"
)
func assertTreeImplementation() {
var _ trees.Tree = new(Tree)
}
// Tree holds elements of the AVL tree.
type Tree struct {
Root *Node // Root node
Comparator utils.Comparator // Key comparator
size int // Total number of keys in the tree
}
// Node is a single element within the tree
type Node struct {
Key interface{}
Value interface{}
Parent *Node // Parent node
Children [2]*Node // Children nodes
b int8
}
// NewWith instantiates an AVL tree with the custom comparator.
func NewWith(comparator utils.Comparator) *Tree {
return &Tree{Comparator: comparator}
}
// NewWithIntComparator instantiates an AVL tree with the IntComparator, i.e. keys are of type int.
func NewWithIntComparator() *Tree {
return &Tree{Comparator: utils.IntComparator}
}
// NewWithStringComparator instantiates an AVL tree with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator() *Tree {
return &Tree{Comparator: utils.StringComparator}
}
// Put inserts node into the tree.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (t *Tree) Put(key interface{}, value interface{}) {
t.put(key, value, nil, &t.Root)
}
// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.
// Second return parameter is true if key was found, otherwise false.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (t *Tree) Get(key interface{}) (value interface{}, found bool) {
n := t.Root
for n != nil {
cmp := t.Comparator(key, n.Key)
switch {
case cmp == 0:
return n.Value, true
case cmp < 0:
n = n.Children[0]
case cmp > 0:
n = n.Children[1]
}
}
return nil, false
}
// Remove remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (t *Tree) Remove(key interface{}) {
t.remove(key, &t.Root)
}
// Empty returns true if tree does not contain any nodes.
func (t *Tree) Empty() bool {
return t.size == 0
}
// Size returns the number of elements stored in the tree.
func (t *Tree) Size() int {
return t.size
}
// Keys returns all keys in-order
func (t *Tree) Keys() []interface{} {
keys := make([]interface{}, t.size)
it := t.Iterator()
for i := 0; it.Next(); i++ {
keys[i] = it.Key()
}
return keys
}
// Values returns all values in-order based on the key.
func (t *Tree) Values() []interface{} {
values := make([]interface{}, t.size)
it := t.Iterator()
for i := 0; it.Next(); i++ {
values[i] = it.Value()
}
return values
}
// Left returns the minimum element of the AVL tree
// or nil if the tree is empty.
func (t *Tree) Left() *Node {
return t.bottom(0)
}
// Right returns the maximum element of the AVL tree
// or nil if the tree is empty.
func (t *Tree) Right() *Node {
return t.bottom(1)
}
// Floor Finds floor node of the input key, return the floor node or nil if no ceiling is found.
// Second return parameter is true if floor was found, otherwise false.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree is larger than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (t *Tree) Floor(key interface{}) (floor *Node, found bool) {
found = false
n := t.Root
for n != nil {
c := t.Comparator(key, n.Key)
switch {
case c == 0:
return n, true
case c < 0:
n = n.Children[0]
case c > 0:
floor, found = n, true
n = n.Children[1]
}
}
if found {
return
}
return nil, false
}
// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
// Second return parameter is true if ceiling was found, otherwise false.
//
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
// A ceiling node may not be found, either because the tree is empty, or because
// all nodes in the tree is smaller than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (t *Tree) Ceiling(key interface{}) (floor *Node, found bool) {
found = false
n := t.Root
for n != nil {
c := t.Comparator(key, n.Key)
switch {
case c == 0:
return n, true
case c < 0:
floor, found = n, true
n = n.Children[0]
case c > 0:
n = n.Children[1]
}
}
if found {
return
}
return nil, false
}
// Clear removes all nodes from the tree.
func (t *Tree) Clear() {
t.Root = nil
t.size = 0
}
// String returns a string representation of container
func (t *Tree) String() string {
str := "AVLTree\n"
if !t.Empty() {
output(t.Root, "", true, &str)
}
return str
}
func (n *Node) String() string {
return fmt.Sprintf("%v", n.Key)
}
func (t *Tree) put(key interface{}, value interface{}, p *Node, qp **Node) bool {
q := *qp
if q == nil {
t.size++
*qp = &Node{Key: key, Value: value, Parent: p}
return true
}
c := t.Comparator(key, q.Key)
if c == 0 {
q.Key = key
q.Value = value
return false
}
if c < 0 {
c = -1
} else {
c = 1
}
a := (c + 1) / 2
var fix bool
fix = t.put(key, value, q, &q.Children[a])
if fix {
return putFix(int8(c), qp)
}
return false
}
func (t *Tree) remove(key interface{}, qp **Node) bool {
q := *qp
if q == nil {
return false
}
c := t.Comparator(key, q.Key)
if c == 0 {
t.size--
if q.Children[1] == nil {
if q.Children[0] != nil {
q.Children[0].Parent = q.Parent
}
*qp = q.Children[0]
return true
}
fix := removeMin(&q.Children[1], &q.Key, &q.Value)
if fix {
return removeFix(-1, qp)
}
return false
}
if c < 0 {
c = -1
} else {
c = 1
}
a := (c + 1) / 2
fix := t.remove(key, &q.Children[a])
if fix {
return removeFix(int8(-c), qp)
}
return false
}
func removeMin(qp **Node, minKey *interface{}, minVal *interface{}) bool {
q := *qp
if q.Children[0] == nil {
*minKey = q.Key
*minVal = q.Value
if q.Children[1] != nil {
q.Children[1].Parent = q.Parent
}
*qp = q.Children[1]
return true
}
fix := removeMin(&q.Children[0], minKey, minVal)
if fix {
return removeFix(1, qp)
}
return false
}
func putFix(c int8, t **Node) bool {
s := *t
if s.b == 0 {
s.b = c
return true
}
if s.b == -c {
s.b = 0
return false
}
if s.Children[(c+1)/2].b == c {
s = singlerot(c, s)
} else {
s = doublerot(c, s)
}
*t = s
return false
}
func removeFix(c int8, t **Node) bool {
s := *t
if s.b == 0 {
s.b = c
return false
}
if s.b == -c {
s.b = 0
return true
}
a := (c + 1) / 2
if s.Children[a].b == 0 {
s = rotate(c, s)
s.b = -c
*t = s
return false
}
if s.Children[a].b == c {
s = singlerot(c, s)
} else {
s = doublerot(c, s)
}
*t = s
return true
}
func singlerot(c int8, s *Node) *Node {
s.b = 0
s = rotate(c, s)
s.b = 0
return s
}
func doublerot(c int8, s *Node) *Node {
a := (c + 1) / 2
r := s.Children[a]
s.Children[a] = rotate(-c, s.Children[a])
p := rotate(c, s)
switch {
default:
s.b = 0
r.b = 0
case p.b == c:
s.b = -c
r.b = 0
case p.b == -c:
s.b = 0
r.b = c
}
p.b = 0
return p
}
func rotate(c int8, s *Node) *Node {
a := (c + 1) / 2
r := s.Children[a]
s.Children[a] = r.Children[a^1]
if s.Children[a] != nil {
s.Children[a].Parent = s
}
r.Children[a^1] = s
r.Parent = s.Parent
s.Parent = r
return r
}
func (t *Tree) bottom(d int) *Node {
n := t.Root
if n == nil {
return nil
}
for c := n.Children[d]; c != nil; c = n.Children[d] {
n = c
}
return n
}
// Prev returns the previous element in an inorder
// walk of the AVL tree.
func (n *Node) Prev() *Node {
return n.walk1(0)
}
// Next returns the next element in an inorder
// walk of the AVL tree.
func (n *Node) Next() *Node {
return n.walk1(1)
}
func (n *Node) walk1(a int) *Node {
if n == nil {
return nil
}
if n.Children[a] != nil {
n = n.Children[a]
for n.Children[a^1] != nil {
n = n.Children[a^1]
}
return n
}
p := n.Parent
for p != nil && p.Children[a] == n {
n = p
p = p.Parent
}
return p
}
func output(node *Node, prefix string, isTail bool, str *string) {
if node.Children[1] != nil {
newPrefix := prefix
if isTail {
newPrefix += "│ "
} else {
newPrefix += " "
}
output(node.Children[1], newPrefix, false, str)
}
*str += prefix
if isTail {
*str += "└── "
} else {
*str += "┌── "
}
*str += node.String() + "\n"
if node.Children[0] != nil {
newPrefix := prefix
if isTail {
newPrefix += " "
} else {
newPrefix += "│ "
}
output(node.Children[0], newPrefix, true, str)
}
}

View file

@ -0,0 +1,741 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package avltree
import (
"fmt"
"testing"
)
func TestAVLTreePut(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
if actualValue := tree.Size(); actualValue != 7 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "abcdefg"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := tree.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
}
func TestAVLTreeRemove(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
tree.Remove(5)
tree.Remove(6)
tree.Remove(7)
tree.Remove(8)
tree.Remove(5)
if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := tree.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
tests2 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
}
for _, test := range tests2 {
actualValue, actualFound := tree.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
tree.Remove(1)
tree.Remove(4)
tree.Remove(2)
tree.Remove(3)
tree.Remove(2)
tree.Remove(2)
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 {
t.Errorf("Got %v expected %v", empty, true)
}
}
func TestAVLTreeLeftAndRight(t *testing.T) {
tree := NewWithIntComparator()
if actualValue := tree.Left(); actualValue != nil {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := tree.Right(); actualValue != nil {
t.Errorf("Got %v expected %v", actualValue, nil)
}
tree.Put(1, "a")
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x") // overwrite
tree.Put(2, "b")
if actualValue, expectedValue := fmt.Sprintf("%d", tree.Left().Key), "1"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Left().Value), "x"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%d", tree.Right().Key), "7"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Right().Value), "g"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeCeilingAndFloor(t *testing.T) {
tree := NewWithIntComparator()
if node, found := tree.Floor(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
if node, found := tree.Ceiling(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
if node, found := tree.Floor(4); node.Key != 4 || !found {
t.Errorf("Got %v expected %v", node.Key, 4)
}
if node, found := tree.Floor(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
if node, found := tree.Ceiling(4); node.Key != 4 || !found {
t.Errorf("Got %v expected %v", node.Key, 4)
}
if node, found := tree.Ceiling(8); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
}
func TestAVLTreeIteratorNextOnEmpty(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty tree")
}
}
func TestAVLTreeIteratorPrevOnEmpty(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty tree")
}
}
func TestAVLTreeIterator1Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
// │ ┌── 7
// └── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
it := tree.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
switch key {
case count:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator1Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
// │ ┌── 7
// └── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator2Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
switch key {
case count:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator2Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator3Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(1, "a")
it := tree.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
switch key {
case count:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator3Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(1, "a")
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator4Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(13, 5)
tree.Put(8, 3)
tree.Put(17, 7)
tree.Put(1, 1)
tree.Put(11, 4)
tree.Put(15, 6)
tree.Put(25, 9)
tree.Put(6, 2)
tree.Put(22, 8)
tree.Put(27, 10)
// │ ┌── 27
// │ ┌── 25
// │ │ └── 22
// │ ┌── 17
// │ │ └── 15
// └── 13
// │ ┌── 11
// └── 8
// │ ┌── 6
// └── 1
it := tree.Iterator()
count := 0
for it.Next() {
count++
value := it.Value()
switch value {
case count:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIterator4Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(13, 5)
tree.Put(8, 3)
tree.Put(17, 7)
tree.Put(1, 1)
tree.Put(11, 4)
tree.Put(15, 6)
tree.Put(25, 9)
tree.Put(6, 2)
tree.Put(22, 8)
tree.Put(27, 10)
// │ ┌── 27
// │ ┌── 25
// │ │ └── 22
// │ ┌── 17
// │ │ └── 15
// └── 13
// │ ┌── 11
// └── 8
// │ ┌── 6
// └── 1
it := tree.Iterator()
count := tree.Size()
for it.Next() {
}
for it.Prev() {
value := it.Value()
switch value {
case count:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
count--
}
if actualValue, expectedValue := count, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestAVLTreeIteratorBegin(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if it.Key() != nil {
t.Errorf("Got %v expected %v", it.Key(), nil)
}
it.Begin()
if it.Key() != nil {
t.Errorf("Got %v expected %v", it.Key(), nil)
}
for it.Next() {
}
it.Begin()
if it.Key() != nil {
t.Errorf("Got %v expected %v", it.Key(), nil)
}
it.Next()
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestAVLTreeIteratorEnd(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
if it.Key() != nil {
t.Errorf("Got %v expected %v", it.Key(), nil)
}
it.End()
if it.Key() != nil {
t.Errorf("Got %v expected %v", it.Key(), nil)
}
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it.End()
if it.Key() != nil {
t.Errorf("Got %v expected %v", it.Key(), nil)
}
it.Prev()
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestAVLTreeIteratorFirst(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestAVLTreeIteratorLast(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestAVLTreeSerialization(t *testing.T) {
tree := NewWithStringComparator()
tree.Put("c", "3")
tree.Put("b", "2")
tree.Put("a", "1")
var err error
assert := func() {
if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" {
t.Errorf("Got %v expected %v", actualValue, "[a,b,c]")
}
if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := tree.ToJSON()
assert()
err = tree.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Get(n)
}
}
}
func benchmarkPut(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Remove(n)
}
}
}
func BenchmarkAVLTreeGet100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkAVLTreeGet1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkAVLTreeGet10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkAVLTreeGet100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkAVLTreePut100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkAVLTreePut1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkAVLTreePut10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkAVLTreePut100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkAVLTreeRemove100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkAVLTreeRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkAVLTreeRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkAVLTreeRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}

View file

@ -0,0 +1,117 @@
// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package avltree
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
tree *Tree
node *Node
position position
}
type position byte
const (
begin, between, end position = 0, 1, 2
)
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator() containers.ReverseIteratorWithKey {
return &Iterator{tree: tree, node: nil, position: begin}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
switch iterator.position {
case begin:
iterator.position = between
iterator.node = iterator.tree.Left()
case between:
iterator.node = iterator.node.Next()
}
if iterator.node == nil {
iterator.position = end
return false
}
return true
}
// Prev moves the iterator to the next element and returns true if there was a previous element in the container.
// If Prev() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Prev() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
switch iterator.position {
case end:
iterator.position = between
iterator.node = iterator.tree.Right()
case between:
iterator.node = iterator.node.Prev()
}
if iterator.node == nil {
iterator.position = begin
return false
}
return true
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
if iterator.node == nil {
return nil
}
return iterator.node.Value
}
// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} {
if iterator.node == nil {
return nil
}
return iterator.node.Key
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.node = nil
iterator.position = begin
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.node = nil
iterator.position = end
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,39 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package avltree
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
"github.com/emirpasic/gods/utils"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Tree)(nil)
var _ containers.JSONDeserializer = (*Tree)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (tree *Tree) ToJSON() ([]byte, error) {
elements := make(map[string]interface{})
it := tree.Iterator()
for it.Next() {
elements[utils.ToString(it.Key())] = it.Value()
}
return json.Marshal(&elements)
}
// FromJSON populates list's elements from the input JSON representation.
func (tree *Tree) FromJSON(data []byte) error {
elements := make(map[string]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
tree.Clear()
for key, value := range elements {
tree.Put(key, value)
}
}
return err
}

View file

@ -0,0 +1,163 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package binaryheap implements a binary heap backed by array list.
//
// Comparator defines this heap as either min or max heap.
//
// Structure is not thread safe.
//
// References: http://en.wikipedia.org/wiki/Binary_heap
package binaryheap
import (
"fmt"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/trees"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertTreeImplementation() {
var _ trees.Tree = (*Heap)(nil)
}
// Heap holds elements in an array-list
type Heap struct {
list *arraylist.List
Comparator utils.Comparator
}
// NewWith instantiates a new empty heap tree with the custom comparator.
func NewWith(comparator utils.Comparator) *Heap {
return &Heap{list: arraylist.New(), Comparator: comparator}
}
// NewWithIntComparator instantiates a new empty heap with the IntComparator, i.e. elements are of type int.
func NewWithIntComparator() *Heap {
return &Heap{list: arraylist.New(), Comparator: utils.IntComparator}
}
// NewWithStringComparator instantiates a new empty heap with the StringComparator, i.e. elements are of type string.
func NewWithStringComparator() *Heap {
return &Heap{list: arraylist.New(), Comparator: utils.StringComparator}
}
// Push adds a value onto the heap and bubbles it up accordingly.
func (heap *Heap) Push(values ...interface{}) {
if len(values) == 1 {
heap.list.Add(values[0])
heap.bubbleUp()
} else {
// Reference: https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap
for _, value := range values {
heap.list.Add(value)
}
size := heap.list.Size()/2 + 1
for i := size; i >= 0; i-- {
heap.bubbleDownIndex(i)
}
}
}
// Pop removes top element on heap and returns it, or nil if heap is empty.
// Second return parameter is true, unless the heap was empty and there was nothing to pop.
func (heap *Heap) Pop() (value interface{}, ok bool) {
value, ok = heap.list.Get(0)
if !ok {
return
}
lastIndex := heap.list.Size() - 1
heap.list.Swap(0, lastIndex)
heap.list.Remove(lastIndex)
heap.bubbleDown()
return
}
// Peek returns top element on the heap without removing it, or nil if heap is empty.
// Second return parameter is true, unless the heap was empty and there was nothing to peek.
func (heap *Heap) Peek() (value interface{}, ok bool) {
return heap.list.Get(0)
}
// Empty returns true if heap does not contain any elements.
func (heap *Heap) Empty() bool {
return heap.list.Empty()
}
// Size returns number of elements within the heap.
func (heap *Heap) Size() int {
return heap.list.Size()
}
// Clear removes all elements from the heap.
func (heap *Heap) Clear() {
heap.list.Clear()
}
// Values returns all elements in the heap.
func (heap *Heap) Values() []interface{} {
return heap.list.Values()
}
// String returns a string representation of container
func (heap *Heap) String() string {
str := "BinaryHeap\n"
values := []string{}
for _, value := range heap.list.Values() {
values = append(values, fmt.Sprintf("%v", value))
}
str += strings.Join(values, ", ")
return str
}
// Performs the "bubble down" operation. This is to place the element that is at the root
// of the heap in its correct place so that the heap maintains the min/max-heap order property.
func (heap *Heap) bubbleDown() {
heap.bubbleDownIndex(0)
}
// Performs the "bubble down" operation. This is to place the element that is at the index
// of the heap in its correct place so that the heap maintains the min/max-heap order property.
func (heap *Heap) bubbleDownIndex(index int) {
size := heap.list.Size()
for leftIndex := index<<1 + 1; leftIndex < size; leftIndex = index<<1 + 1 {
rightIndex := index<<1 + 2
smallerIndex := leftIndex
leftValue, _ := heap.list.Get(leftIndex)
rightValue, _ := heap.list.Get(rightIndex)
if rightIndex < size && heap.Comparator(leftValue, rightValue) > 0 {
smallerIndex = rightIndex
}
indexValue, _ := heap.list.Get(index)
smallerValue, _ := heap.list.Get(smallerIndex)
if heap.Comparator(indexValue, smallerValue) > 0 {
heap.list.Swap(index, smallerIndex)
} else {
break
}
index = smallerIndex
}
}
// Performs the "bubble up" operation. This is to place a newly inserted
// element (i.e. last element in the list) in its correct place so that
// the heap maintains the min/max-heap order property.
func (heap *Heap) bubbleUp() {
index := heap.list.Size() - 1
for parentIndex := (index - 1) >> 1; index > 0; parentIndex = (index - 1) >> 1 {
indexValue, _ := heap.list.Get(index)
parentValue, _ := heap.list.Get(parentIndex)
if heap.Comparator(parentValue, indexValue) <= 0 {
break
}
heap.list.Swap(index, parentIndex)
index = parentIndex
}
}
// Check that the index is within bounds of the list
func (heap *Heap) withinRange(index int) bool {
return index >= 0 && index < heap.list.Size()
}

View file

@ -0,0 +1,393 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package binaryheap
import (
"math/rand"
"testing"
)
func TestBinaryHeapPush(t *testing.T) {
heap := NewWithIntComparator()
if actualValue := heap.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
if actualValue := heap.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 3 || actualValue[2].(int) != 2 {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if actualValue := heap.Empty(); actualValue != false {
t.Errorf("Got %v expected %v", actualValue, false)
}
if actualValue := heap.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := heap.Peek(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
}
func TestBinaryHeapPushBulk(t *testing.T) {
heap := NewWithIntComparator()
heap.Push(15, 20, 3, 1, 2)
if actualValue := heap.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 2 || actualValue[2].(int) != 3 {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if actualValue, ok := heap.Pop(); actualValue != 1 || !ok {
t.Errorf("Got %v expected %v", actualValue, 1)
}
}
func TestBinaryHeapPop(t *testing.T) {
heap := NewWithIntComparator()
if actualValue := heap.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
heap.Pop() // [3,2]
if actualValue, ok := heap.Peek(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := heap.Pop(); actualValue != 2 || !ok {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue, ok := heap.Pop(); actualValue != 3 || !ok {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := heap.Pop(); actualValue != nil || ok {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := heap.Empty(); actualValue != true {
t.Errorf("Got %v expected %v", actualValue, true)
}
if actualValue := heap.Values(); len(actualValue) != 0 {
t.Errorf("Got %v expected %v", actualValue, "[]")
}
}
func TestBinaryHeapRandom(t *testing.T) {
heap := NewWithIntComparator()
rand.Seed(3)
for i := 0; i < 10000; i++ {
r := int(rand.Int31n(30))
heap.Push(r)
}
prev, _ := heap.Pop()
for !heap.Empty() {
curr, _ := heap.Pop()
if prev.(int) > curr.(int) {
t.Errorf("Heap property invalidated. prev: %v current: %v", prev, curr)
}
prev = curr
}
}
func TestBinaryHeapIteratorOnEmpty(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty heap")
}
}
func TestBinaryHeapIteratorNext(t *testing.T) {
heap := NewWithIntComparator()
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
it := heap.Iterator()
count := 0
for it.Next() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, 1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, 2; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, count-1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestBinaryHeapIteratorPrev(t *testing.T) {
heap := NewWithIntComparator()
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
it := heap.Iterator()
for it.Next() {
}
count := 0
for it.Prev() {
count++
index := it.Index()
value := it.Value()
switch index {
case 0:
if actualValue, expectedValue := value, 1; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 1:
if actualValue, expectedValue := value, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
case 2:
if actualValue, expectedValue := value, 2; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
t.Errorf("Too many")
}
if actualValue, expectedValue := index, 3-count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
if actualValue, expectedValue := count, 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestBinaryHeapIteratorBegin(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
it.Begin()
heap.Push(2)
heap.Push(3)
heap.Push(1)
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != 1 {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1)
}
}
func TestListIteratorEnd(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
it.End()
if index := it.Index(); index != heap.Size() {
t.Errorf("Got %v expected %v", index, heap.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != heap.Size()-1 || value != 2 {
t.Errorf("Got %v,%v expected %v,%v", index, value, heap.Size()-1, 2)
}
}
func TestStackIteratorFirst(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != 1 {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1)
}
}
func TestBinaryHeapIteratorLast(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
tree.Push(2)
tree.Push(3)
tree.Push(1) // [1,3,2](2 swapped with 1, hence last)
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != 2 {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, 2)
}
}
func TestBinaryHeapSerialization(t *testing.T) {
heap := NewWithStringComparator()
heap.Push("c") // ["c"]
heap.Push("b") // ["b","c"]
heap.Push("a") // ["a","c","b"]("b" swapped with "a", hence last)
var err error
assert := func() {
if actualValue := heap.Values(); actualValue[0].(string) != "a" || actualValue[1].(string) != "c" || actualValue[2].(string) != "b" {
t.Errorf("Got %v expected %v", actualValue, "[1,3,2]")
}
if actualValue := heap.Size(); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue, ok := heap.Peek(); actualValue != "a" || !ok {
t.Errorf("Got %v expected %v", actualValue, "a")
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := heap.ToJSON()
assert()
err = heap.FromJSON(json)
assert()
}
func benchmarkPush(b *testing.B, heap *Heap, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
heap.Push(n)
}
}
}
func benchmarkPop(b *testing.B, heap *Heap, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
heap.Pop()
}
}
}
func BenchmarkBinaryHeapPop100(b *testing.B) {
b.StopTimer()
size := 100
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPop1000(b *testing.B) {
b.StopTimer()
size := 1000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPop10000(b *testing.B) {
b.StopTimer()
size := 10000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPop100000(b *testing.B) {
b.StopTimer()
size := 100000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPop(b, heap, size)
}
func BenchmarkBinaryHeapPush100(b *testing.B) {
b.StopTimer()
size := 100
heap := NewWithIntComparator()
b.StartTimer()
benchmarkPush(b, heap, size)
}
func BenchmarkBinaryHeapPush1000(b *testing.B) {
b.StopTimer()
size := 1000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPush(b, heap, size)
}
func BenchmarkBinaryHeapPush10000(b *testing.B) {
b.StopTimer()
size := 10000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPush(b, heap, size)
}
func BenchmarkBinaryHeapPush100000(b *testing.B) {
b.StopTimer()
size := 100000
heap := NewWithIntComparator()
for n := 0; n < size; n++ {
heap.Push(n)
}
b.StartTimer()
benchmarkPush(b, heap, size)
}

View file

@ -0,0 +1,84 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package binaryheap
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
type Iterator struct {
heap *Heap
index int
}
// Iterator returns a stateful iterator whose values can be fetched by an index.
func (heap *Heap) Iterator() Iterator {
return Iterator{heap: heap, index: -1}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.heap.Size() {
iterator.index++
}
return iterator.heap.withinRange(iterator.index)
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
return iterator.heap.withinRange(iterator.index)
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
value, _ := iterator.heap.list.Get(iterator.index)
return value
}
// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.heap.Size()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package binaryheap
import "github.com/emirpasic/gods/containers"
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Heap)(nil)
var _ containers.JSONDeserializer = (*Heap)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (heap *Heap) ToJSON() ([]byte, error) {
return heap.list.ToJSON()
}
// FromJSON populates list's elements from the input JSON representation.
func (heap *Heap) FromJSON(data []byte) error {
return heap.list.FromJSON(data)
}

577
vendor/github.com/emirpasic/gods/trees/btree/btree.go generated vendored Normal file
View file

@ -0,0 +1,577 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package btree implements a B tree.
//
// According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties:
// - Every node has at most m children.
// - Every non-leaf node (except root) has at least ⌈m/2⌉ children.
// - The root has at least two children if it is not a leaf node.
// - A non-leaf node with k children contains k1 keys.
// - All leaves appear in the same level
//
// Structure is not thread safe.
//
// References: https://en.wikipedia.org/wiki/B-tree
package btree
import (
"bytes"
"fmt"
"github.com/emirpasic/gods/trees"
"github.com/emirpasic/gods/utils"
"strings"
)
func assertTreeImplementation() {
var _ trees.Tree = (*Tree)(nil)
}
// Tree holds elements of the B-tree
type Tree struct {
Root *Node // Root node
Comparator utils.Comparator // Key comparator
size int // Total number of keys in the tree
m int // order (maximum number of children)
}
// Node is a single element within the tree
type Node struct {
Parent *Node
Entries []*Entry // Contained keys in node
Children []*Node // Children nodes
}
// Entry represents the key-value pair contained within nodes
type Entry struct {
Key interface{}
Value interface{}
}
// NewWith instantiates a B-tree with the order (maximum number of children) and a custom key comparator.
func NewWith(order int, comparator utils.Comparator) *Tree {
if order < 3 {
panic("Invalid order, should be at least 3")
}
return &Tree{m: order, Comparator: comparator}
}
// NewWithIntComparator instantiates a B-tree with the order (maximum number of children) and the IntComparator, i.e. keys are of type int.
func NewWithIntComparator(order int) *Tree {
return NewWith(order, utils.IntComparator)
}
// NewWithStringComparator instantiates a B-tree with the order (maximum number of children) and the StringComparator, i.e. keys are of type string.
func NewWithStringComparator(order int) *Tree {
return NewWith(order, utils.StringComparator)
}
// Put inserts key-value pair node into the tree.
// If key already exists, then its value is updated with the new value.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Put(key interface{}, value interface{}) {
entry := &Entry{Key: key, Value: value}
if tree.Root == nil {
tree.Root = &Node{Entries: []*Entry{entry}, Children: []*Node{}}
tree.size++
return
}
if tree.insert(tree.Root, entry) {
tree.size++
}
}
// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.
// Second return parameter is true if key was found, otherwise false.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Get(key interface{}) (value interface{}, found bool) {
node, index, found := tree.searchRecursively(tree.Root, key)
if found {
return node.Entries[index].Value, true
}
return nil, false
}
// Remove remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Remove(key interface{}) {
node, index, found := tree.searchRecursively(tree.Root, key)
if found {
tree.delete(node, index)
tree.size--
}
}
// Empty returns true if tree does not contain any nodes
func (tree *Tree) Empty() bool {
return tree.size == 0
}
// Size returns number of nodes in the tree.
func (tree *Tree) Size() int {
return tree.size
}
// Keys returns all keys in-order
func (tree *Tree) Keys() []interface{} {
keys := make([]interface{}, tree.size)
it := tree.Iterator()
for i := 0; it.Next(); i++ {
keys[i] = it.Key()
}
return keys
}
// Values returns all values in-order based on the key.
func (tree *Tree) Values() []interface{} {
values := make([]interface{}, tree.size)
it := tree.Iterator()
for i := 0; it.Next(); i++ {
values[i] = it.Value()
}
return values
}
// Clear removes all nodes from the tree.
func (tree *Tree) Clear() {
tree.Root = nil
tree.size = 0
}
// Height returns the height of the tree.
func (tree *Tree) Height() int {
return tree.Root.height()
}
// Left returns the left-most (min) node or nil if tree is empty.
func (tree *Tree) Left() *Node {
return tree.left(tree.Root)
}
// LeftKey returns the left-most (min) key or nil if tree is empty.
func (tree *Tree) LeftKey() interface{} {
if left := tree.Left(); left != nil {
return left.Entries[0].Key
}
return nil
}
// LeftValue returns the left-most value or nil if tree is empty.
func (tree *Tree) LeftValue() interface{} {
if left := tree.Left(); left != nil {
return left.Entries[0].Value
}
return nil
}
// Right returns the right-most (max) node or nil if tree is empty.
func (tree *Tree) Right() *Node {
return tree.right(tree.Root)
}
// RightKey returns the right-most (max) key or nil if tree is empty.
func (tree *Tree) RightKey() interface{} {
if right := tree.Right(); right != nil {
return right.Entries[len(right.Entries)-1].Key
}
return nil
}
// RightValue returns the right-most value or nil if tree is empty.
func (tree *Tree) RightValue() interface{} {
if right := tree.Right(); right != nil {
return right.Entries[len(right.Entries)-1].Value
}
return nil
}
// String returns a string representation of container (for debugging purposes)
func (tree *Tree) String() string {
var buffer bytes.Buffer
if _, err := buffer.WriteString("BTree\n"); err != nil {
}
if !tree.Empty() {
tree.output(&buffer, tree.Root, 0, true)
}
return buffer.String()
}
func (entry *Entry) String() string {
return fmt.Sprintf("%v", entry.Key)
}
func (tree *Tree) output(buffer *bytes.Buffer, node *Node, level int, isTail bool) {
for e := 0; e < len(node.Entries)+1; e++ {
if e < len(node.Children) {
tree.output(buffer, node.Children[e], level+1, true)
}
if e < len(node.Entries) {
if _, err := buffer.WriteString(strings.Repeat(" ", level)); err != nil {
}
if _, err := buffer.WriteString(fmt.Sprintf("%v", node.Entries[e].Key) + "\n"); err != nil {
}
}
}
}
func (node *Node) height() int {
height := 0
for ; node != nil; node = node.Children[0] {
height++
if len(node.Children) == 0 {
break
}
}
return height
}
func (tree *Tree) isLeaf(node *Node) bool {
return len(node.Children) == 0
}
func (tree *Tree) isFull(node *Node) bool {
return len(node.Entries) == tree.maxEntries()
}
func (tree *Tree) shouldSplit(node *Node) bool {
return len(node.Entries) > tree.maxEntries()
}
func (tree *Tree) maxChildren() int {
return tree.m
}
func (tree *Tree) minChildren() int {
return (tree.m + 1) / 2 // ceil(m/2)
}
func (tree *Tree) maxEntries() int {
return tree.maxChildren() - 1
}
func (tree *Tree) minEntries() int {
return tree.minChildren() - 1
}
func (tree *Tree) middle() int {
return (tree.m - 1) / 2 // "-1" to favor right nodes to have more keys when splitting
}
// search searches only within the single node among its entries
func (tree *Tree) search(node *Node, key interface{}) (index int, found bool) {
low, high := 0, len(node.Entries)-1
var mid int
for low <= high {
mid = (high + low) / 2
compare := tree.Comparator(key, node.Entries[mid].Key)
switch {
case compare > 0:
low = mid + 1
case compare < 0:
high = mid - 1
case compare == 0:
return mid, true
}
}
return low, false
}
// searchRecursively searches recursively down the tree starting at the startNode
func (tree *Tree) searchRecursively(startNode *Node, key interface{}) (node *Node, index int, found bool) {
if tree.Empty() {
return nil, -1, false
}
node = startNode
for {
index, found = tree.search(node, key)
if found {
return node, index, true
}
if tree.isLeaf(node) {
return nil, -1, false
}
node = node.Children[index]
}
}
func (tree *Tree) insert(node *Node, entry *Entry) (inserted bool) {
if tree.isLeaf(node) {
return tree.insertIntoLeaf(node, entry)
}
return tree.insertIntoInternal(node, entry)
}
func (tree *Tree) insertIntoLeaf(node *Node, entry *Entry) (inserted bool) {
insertPosition, found := tree.search(node, entry.Key)
if found {
node.Entries[insertPosition] = entry
return false
}
// Insert entry's key in the middle of the node
node.Entries = append(node.Entries, nil)
copy(node.Entries[insertPosition+1:], node.Entries[insertPosition:])
node.Entries[insertPosition] = entry
tree.split(node)
return true
}
func (tree *Tree) insertIntoInternal(node *Node, entry *Entry) (inserted bool) {
insertPosition, found := tree.search(node, entry.Key)
if found {
node.Entries[insertPosition] = entry
return false
}
return tree.insert(node.Children[insertPosition], entry)
}
func (tree *Tree) split(node *Node) {
if !tree.shouldSplit(node) {
return
}
if node == tree.Root {
tree.splitRoot()
return
}
tree.splitNonRoot(node)
}
func (tree *Tree) splitNonRoot(node *Node) {
middle := tree.middle()
parent := node.Parent
left := &Node{Entries: append([]*Entry(nil), node.Entries[:middle]...), Parent: parent}
right := &Node{Entries: append([]*Entry(nil), node.Entries[middle+1:]...), Parent: parent}
// Move children from the node to be split into left and right nodes
if !tree.isLeaf(node) {
left.Children = append([]*Node(nil), node.Children[:middle+1]...)
right.Children = append([]*Node(nil), node.Children[middle+1:]...)
setParent(left.Children, left)
setParent(right.Children, right)
}
insertPosition, _ := tree.search(parent, node.Entries[middle].Key)
// Insert middle key into parent
parent.Entries = append(parent.Entries, nil)
copy(parent.Entries[insertPosition+1:], parent.Entries[insertPosition:])
parent.Entries[insertPosition] = node.Entries[middle]
// Set child left of inserted key in parent to the created left node
parent.Children[insertPosition] = left
// Set child right of inserted key in parent to the created right node
parent.Children = append(parent.Children, nil)
copy(parent.Children[insertPosition+2:], parent.Children[insertPosition+1:])
parent.Children[insertPosition+1] = right
tree.split(parent)
}
func (tree *Tree) splitRoot() {
middle := tree.middle()
left := &Node{Entries: append([]*Entry(nil), tree.Root.Entries[:middle]...)}
right := &Node{Entries: append([]*Entry(nil), tree.Root.Entries[middle+1:]...)}
// Move children from the node to be split into left and right nodes
if !tree.isLeaf(tree.Root) {
left.Children = append([]*Node(nil), tree.Root.Children[:middle+1]...)
right.Children = append([]*Node(nil), tree.Root.Children[middle+1:]...)
setParent(left.Children, left)
setParent(right.Children, right)
}
// Root is a node with one entry and two children (left and right)
newRoot := &Node{
Entries: []*Entry{tree.Root.Entries[middle]},
Children: []*Node{left, right},
}
left.Parent = newRoot
right.Parent = newRoot
tree.Root = newRoot
}
func setParent(nodes []*Node, parent *Node) {
for _, node := range nodes {
node.Parent = parent
}
}
func (tree *Tree) left(node *Node) *Node {
if tree.Empty() {
return nil
}
current := node
for {
if tree.isLeaf(current) {
return current
}
current = current.Children[0]
}
}
func (tree *Tree) right(node *Node) *Node {
if tree.Empty() {
return nil
}
current := node
for {
if tree.isLeaf(current) {
return current
}
current = current.Children[len(current.Children)-1]
}
}
// leftSibling returns the node's left sibling and child index (in parent) if it exists, otherwise (nil,-1)
// key is any of keys in node (could even be deleted).
func (tree *Tree) leftSibling(node *Node, key interface{}) (*Node, int) {
if node.Parent != nil {
index, _ := tree.search(node.Parent, key)
index--
if index >= 0 && index < len(node.Parent.Children) {
return node.Parent.Children[index], index
}
}
return nil, -1
}
// rightSibling returns the node's right sibling and child index (in parent) if it exists, otherwise (nil,-1)
// key is any of keys in node (could even be deleted).
func (tree *Tree) rightSibling(node *Node, key interface{}) (*Node, int) {
if node.Parent != nil {
index, _ := tree.search(node.Parent, key)
index++
if index < len(node.Parent.Children) {
return node.Parent.Children[index], index
}
}
return nil, -1
}
// delete deletes an entry in node at entries' index
// ref.: https://en.wikipedia.org/wiki/B-tree#Deletion
func (tree *Tree) delete(node *Node, index int) {
// deleting from a leaf node
if tree.isLeaf(node) {
deletedKey := node.Entries[index].Key
tree.deleteEntry(node, index)
tree.rebalance(node, deletedKey)
if len(tree.Root.Entries) == 0 {
tree.Root = nil
}
return
}
// deleting from an internal node
leftLargestNode := tree.right(node.Children[index]) // largest node in the left sub-tree (assumed to exist)
leftLargestEntryIndex := len(leftLargestNode.Entries) - 1
node.Entries[index] = leftLargestNode.Entries[leftLargestEntryIndex]
deletedKey := leftLargestNode.Entries[leftLargestEntryIndex].Key
tree.deleteEntry(leftLargestNode, leftLargestEntryIndex)
tree.rebalance(leftLargestNode, deletedKey)
}
// rebalance rebalances the tree after deletion if necessary and returns true, otherwise false.
// Note that we first delete the entry and then call rebalance, thus the passed deleted key as reference.
func (tree *Tree) rebalance(node *Node, deletedKey interface{}) {
// check if rebalancing is needed
if node == nil || len(node.Entries) >= tree.minEntries() {
return
}
// try to borrow from left sibling
leftSibling, leftSiblingIndex := tree.leftSibling(node, deletedKey)
if leftSibling != nil && len(leftSibling.Entries) > tree.minEntries() {
// rotate right
node.Entries = append([]*Entry{node.Parent.Entries[leftSiblingIndex]}, node.Entries...) // prepend parent's separator entry to node's entries
node.Parent.Entries[leftSiblingIndex] = leftSibling.Entries[len(leftSibling.Entries)-1]
tree.deleteEntry(leftSibling, len(leftSibling.Entries)-1)
if !tree.isLeaf(leftSibling) {
leftSiblingRightMostChild := leftSibling.Children[len(leftSibling.Children)-1]
leftSiblingRightMostChild.Parent = node
node.Children = append([]*Node{leftSiblingRightMostChild}, node.Children...)
tree.deleteChild(leftSibling, len(leftSibling.Children)-1)
}
return
}
// try to borrow from right sibling
rightSibling, rightSiblingIndex := tree.rightSibling(node, deletedKey)
if rightSibling != nil && len(rightSibling.Entries) > tree.minEntries() {
// rotate left
node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1]) // append parent's separator entry to node's entries
node.Parent.Entries[rightSiblingIndex-1] = rightSibling.Entries[0]
tree.deleteEntry(rightSibling, 0)
if !tree.isLeaf(rightSibling) {
rightSiblingLeftMostChild := rightSibling.Children[0]
rightSiblingLeftMostChild.Parent = node
node.Children = append(node.Children, rightSiblingLeftMostChild)
tree.deleteChild(rightSibling, 0)
}
return
}
// merge with siblings
if rightSibling != nil {
// merge with right sibling
node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1])
node.Entries = append(node.Entries, rightSibling.Entries...)
deletedKey = node.Parent.Entries[rightSiblingIndex-1].Key
tree.deleteEntry(node.Parent, rightSiblingIndex-1)
tree.appendChildren(node.Parent.Children[rightSiblingIndex], node)
tree.deleteChild(node.Parent, rightSiblingIndex)
} else if leftSibling != nil {
// merge with left sibling
entries := append([]*Entry(nil), leftSibling.Entries...)
entries = append(entries, node.Parent.Entries[leftSiblingIndex])
node.Entries = append(entries, node.Entries...)
deletedKey = node.Parent.Entries[leftSiblingIndex].Key
tree.deleteEntry(node.Parent, leftSiblingIndex)
tree.prependChildren(node.Parent.Children[leftSiblingIndex], node)
tree.deleteChild(node.Parent, leftSiblingIndex)
}
// make the merged node the root if its parent was the root and the root is empty
if node.Parent == tree.Root && len(tree.Root.Entries) == 0 {
tree.Root = node
node.Parent = nil
return
}
// parent might underflow, so try to rebalance if necessary
tree.rebalance(node.Parent, deletedKey)
}
func (tree *Tree) prependChildren(fromNode *Node, toNode *Node) {
children := append([]*Node(nil), fromNode.Children...)
toNode.Children = append(children, toNode.Children...)
setParent(fromNode.Children, toNode)
}
func (tree *Tree) appendChildren(fromNode *Node, toNode *Node) {
toNode.Children = append(toNode.Children, fromNode.Children...)
setParent(fromNode.Children, toNode)
}
func (tree *Tree) deleteEntry(node *Node, index int) {
copy(node.Entries[index:], node.Entries[index+1:])
node.Entries[len(node.Entries)-1] = nil
node.Entries = node.Entries[:len(node.Entries)-1]
}
func (tree *Tree) deleteChild(node *Node, index int) {
if index >= len(node.Children) {
return
}
copy(node.Children[index:], node.Children[index+1:])
node.Children[len(node.Children)-1] = nil
node.Children = node.Children[:len(node.Children)-1]
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,193 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package btree
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
tree *Tree
node *Node
entry *Entry
position position
}
type position byte
const (
begin, between, end position = 0, 1, 2
)
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator() Iterator {
return Iterator{tree: tree, node: nil, position: begin}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
// If already at end, go to end
if iterator.position == end {
goto end
}
// If at beginning, get the left-most entry in the tree
if iterator.position == begin {
left := iterator.tree.Left()
if left == nil {
goto end
}
iterator.node = left
iterator.entry = left.Entries[0]
goto between
}
{
// Find current entry position in current node
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Try to go down to the child right of the current entry
if e+1 < len(iterator.node.Children) {
iterator.node = iterator.node.Children[e+1]
// Try to go down to the child left of the current node
for len(iterator.node.Children) > 0 {
iterator.node = iterator.node.Children[0]
}
// Return the left-most entry
iterator.entry = iterator.node.Entries[0]
goto between
}
// Above assures that we have reached a leaf node, so return the next entry in current node (if any)
if e+1 < len(iterator.node.Entries) {
iterator.entry = iterator.node.Entries[e+1]
goto between
}
}
// Reached leaf node and there are no entries to the right of the current entry, so go up to the parent
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
// Find next entry position in current node (note: search returns the first equal or bigger than entry)
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Check that there is a next entry position in current node
if e < len(iterator.node.Entries) {
iterator.entry = iterator.node.Entries[e]
goto between
}
}
end:
iterator.End()
return false
between:
iterator.position = between
return true
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
// If already at beginning, go to begin
if iterator.position == begin {
goto begin
}
// If at end, get the right-most entry in the tree
if iterator.position == end {
right := iterator.tree.Right()
if right == nil {
goto begin
}
iterator.node = right
iterator.entry = right.Entries[len(right.Entries)-1]
goto between
}
{
// Find current entry position in current node
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Try to go down to the child left of the current entry
if e < len(iterator.node.Children) {
iterator.node = iterator.node.Children[e]
// Try to go down to the child right of the current node
for len(iterator.node.Children) > 0 {
iterator.node = iterator.node.Children[len(iterator.node.Children)-1]
}
// Return the right-most entry
iterator.entry = iterator.node.Entries[len(iterator.node.Entries)-1]
goto between
}
// Above assures that we have reached a leaf node, so return the previous entry in current node (if any)
if e-1 >= 0 {
iterator.entry = iterator.node.Entries[e-1]
goto between
}
}
// Reached leaf node and there are no entries to the left of the current entry, so go up to the parent
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
// Find previous entry position in current node (note: search returns the first equal or bigger than entry)
e, _ := iterator.tree.search(iterator.node, iterator.entry.Key)
// Check that there is a previous entry position in current node
if e-1 >= 0 {
iterator.entry = iterator.node.Entries[e-1]
goto between
}
}
begin:
iterator.Begin()
return false
between:
iterator.position = between
return true
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.entry.Value
}
// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} {
return iterator.entry.Key
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.node = nil
iterator.position = begin
iterator.entry = nil
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.node = nil
iterator.position = end
iterator.entry = nil
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,39 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package btree
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
"github.com/emirpasic/gods/utils"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Tree)(nil)
var _ containers.JSONDeserializer = (*Tree)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (tree *Tree) ToJSON() ([]byte, error) {
elements := make(map[string]interface{})
it := tree.Iterator()
for it.Next() {
elements[utils.ToString(it.Key())] = it.Value()
}
return json.Marshal(&elements)
}
// FromJSON populates list's elements from the input JSON representation.
func (tree *Tree) FromJSON(data []byte) error {
elements := make(map[string]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
tree.Clear()
for key, value := range elements {
tree.Put(key, value)
}
}
return err
}

View file

@ -0,0 +1,156 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package redblacktree
import "github.com/emirpasic/gods/containers"
func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
}
// Iterator holding the iterator's state
type Iterator struct {
tree *Tree
node *Node
position position
}
type position byte
const (
begin, between, end position = 0, 1, 2
)
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator() Iterator {
return Iterator{tree: tree, node: nil, position: begin}
}
// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.position == end {
goto end
}
if iterator.position == begin {
left := iterator.tree.Left()
if left == nil {
goto end
}
iterator.node = left
goto between
}
if iterator.node.Right != nil {
iterator.node = iterator.node.Right
for iterator.node.Left != nil {
iterator.node = iterator.node.Left
}
goto between
}
if iterator.node.Parent != nil {
node := iterator.node
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 {
goto between
}
}
}
end:
iterator.node = nil
iterator.position = end
return false
between:
iterator.position = between
return true
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.position == begin {
goto begin
}
if iterator.position == end {
right := iterator.tree.Right()
if right == nil {
goto begin
}
iterator.node = right
goto between
}
if iterator.node.Left != nil {
iterator.node = iterator.node.Left
for iterator.node.Right != nil {
iterator.node = iterator.node.Right
}
goto between
}
if iterator.node.Parent != nil {
node := iterator.node
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 {
goto between
}
}
}
begin:
iterator.node = nil
iterator.position = begin
return false
between:
iterator.position = between
return true
}
// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
return iterator.node.Value
}
// Key returns the current element's key.
// Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} {
return iterator.node.Key
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.node = nil
iterator.position = begin
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.node = nil
iterator.position = end
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}

View file

@ -0,0 +1,522 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package redblacktree implements a red-black tree.
//
// Used by TreeSet and TreeMap.
//
// Structure is not thread safe.
//
// References: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
package redblacktree
import (
"fmt"
"github.com/emirpasic/gods/trees"
"github.com/emirpasic/gods/utils"
)
func assertTreeImplementation() {
var _ trees.Tree = (*Tree)(nil)
}
type color bool
const (
black, red color = true, false
)
// Tree holds elements of the red-black tree
type Tree struct {
Root *Node
size int
Comparator utils.Comparator
}
// Node is a single element within the tree
type Node struct {
Key interface{}
Value interface{}
color color
Left *Node
Right *Node
Parent *Node
}
// NewWith instantiates a red-black tree with the custom comparator.
func NewWith(comparator utils.Comparator) *Tree {
return &Tree{Comparator: comparator}
}
// NewWithIntComparator instantiates a red-black tree with the IntComparator, i.e. keys are of type int.
func NewWithIntComparator() *Tree {
return &Tree{Comparator: utils.IntComparator}
}
// NewWithStringComparator instantiates a red-black tree with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator() *Tree {
return &Tree{Comparator: utils.StringComparator}
}
// Put inserts node into the tree.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Put(key interface{}, value interface{}) {
insertedNode := &Node{Key: key, Value: value, color: red}
if tree.Root == nil {
tree.Root = insertedNode
} else {
node := tree.Root
loop := true
for loop {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
node.Key = key
node.Value = value
return
case compare < 0:
if node.Left == nil {
node.Left = insertedNode
loop = false
} else {
node = node.Left
}
case compare > 0:
if node.Right == nil {
node.Right = insertedNode
loop = false
} else {
node = node.Right
}
}
}
insertedNode.Parent = node
}
tree.insertCase1(insertedNode)
tree.size++
}
// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.
// Second return parameter is true if key was found, otherwise false.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Get(key interface{}) (value interface{}, found bool) {
node := tree.lookup(key)
if node != nil {
return node.Value, true
}
return nil, false
}
// Remove remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Remove(key interface{}) {
var child *Node
node := tree.lookup(key)
if node == nil {
return
}
if node.Left != nil && node.Right != nil {
pred := node.Left.maximumNode()
node.Key = pred.Key
node.Value = pred.Value
node = pred
}
if node.Left == nil || node.Right == nil {
if node.Right == nil {
child = node.Left
} else {
child = node.Right
}
if node.color == black {
node.color = nodeColor(child)
tree.deleteCase1(node)
}
tree.replaceNode(node, child)
if node.Parent == nil && child != nil {
child.color = black
}
}
tree.size--
}
// Empty returns true if tree does not contain any nodes
func (tree *Tree) Empty() bool {
return tree.size == 0
}
// Size returns number of nodes in the tree.
func (tree *Tree) Size() int {
return tree.size
}
// Keys returns all keys in-order
func (tree *Tree) Keys() []interface{} {
keys := make([]interface{}, tree.size)
it := tree.Iterator()
for i := 0; it.Next(); i++ {
keys[i] = it.Key()
}
return keys
}
// Values returns all values in-order based on the key.
func (tree *Tree) Values() []interface{} {
values := make([]interface{}, tree.size)
it := tree.Iterator()
for i := 0; it.Next(); i++ {
values[i] = it.Value()
}
return values
}
// Left returns the left-most (min) node or nil if tree is empty.
func (tree *Tree) Left() *Node {
var parent *Node
current := tree.Root
for current != nil {
parent = current
current = current.Left
}
return parent
}
// Right returns the right-most (max) node or nil if tree is empty.
func (tree *Tree) Right() *Node {
var parent *Node
current := tree.Root
for current != nil {
parent = current
current = current.Right
}
return parent
}
// Floor Finds floor node of the input key, return the floor node or nil if no ceiling is found.
// Second return parameter is true if floor was found, otherwise false.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree is larger than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Floor(key interface{}) (floor *Node, found bool) {
found = false
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node, true
case compare < 0:
node = node.Left
case compare > 0:
floor, found = node, true
node = node.Right
}
}
if found {
return floor, true
}
return nil, false
}
// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
// Second return parameter is true if ceiling was found, otherwise false.
//
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
// A ceiling node may not be found, either because the tree is empty, or because
// all nodes in the tree is smaller than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Ceiling(key interface{}) (ceiling *Node, found bool) {
found = false
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node, true
case compare < 0:
ceiling, found = node, true
node = node.Left
case compare > 0:
node = node.Right
}
}
if found {
return ceiling, true
}
return nil, false
}
// Clear removes all nodes from the tree.
func (tree *Tree) Clear() {
tree.Root = nil
tree.size = 0
}
// String returns a string representation of container
func (tree *Tree) String() string {
str := "RedBlackTree\n"
if !tree.Empty() {
output(tree.Root, "", true, &str)
}
return str
}
func (node *Node) String() string {
return fmt.Sprintf("%v", node.Key)
}
func output(node *Node, prefix string, isTail bool, str *string) {
if node.Right != nil {
newPrefix := prefix
if isTail {
newPrefix += "│ "
} else {
newPrefix += " "
}
output(node.Right, newPrefix, false, str)
}
*str += prefix
if isTail {
*str += "└── "
} else {
*str += "┌── "
}
*str += node.String() + "\n"
if node.Left != nil {
newPrefix := prefix
if isTail {
newPrefix += " "
} else {
newPrefix += "│ "
}
output(node.Left, newPrefix, true, str)
}
}
func (tree *Tree) lookup(key interface{}) *Node {
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node
case compare < 0:
node = node.Left
case compare > 0:
node = node.Right
}
}
return nil
}
func (node *Node) grandparent() *Node {
if node != nil && node.Parent != nil {
return node.Parent.Parent
}
return nil
}
func (node *Node) uncle() *Node {
if node == nil || node.Parent == nil || node.Parent.Parent == nil {
return nil
}
return node.Parent.sibling()
}
func (node *Node) sibling() *Node {
if node == nil || node.Parent == nil {
return nil
}
if node == node.Parent.Left {
return node.Parent.Right
}
return node.Parent.Left
}
func (tree *Tree) rotateLeft(node *Node) {
right := node.Right
tree.replaceNode(node, right)
node.Right = right.Left
if right.Left != nil {
right.Left.Parent = node
}
right.Left = node
node.Parent = right
}
func (tree *Tree) rotateRight(node *Node) {
left := node.Left
tree.replaceNode(node, left)
node.Left = left.Right
if left.Right != nil {
left.Right.Parent = node
}
left.Right = node
node.Parent = left
}
func (tree *Tree) replaceNode(old *Node, new *Node) {
if old.Parent == nil {
tree.Root = new
} else {
if old == old.Parent.Left {
old.Parent.Left = new
} else {
old.Parent.Right = new
}
}
if new != nil {
new.Parent = old.Parent
}
}
func (tree *Tree) insertCase1(node *Node) {
if node.Parent == nil {
node.color = black
} else {
tree.insertCase2(node)
}
}
func (tree *Tree) insertCase2(node *Node) {
if nodeColor(node.Parent) == black {
return
}
tree.insertCase3(node)
}
func (tree *Tree) insertCase3(node *Node) {
uncle := node.uncle()
if nodeColor(uncle) == red {
node.Parent.color = black
uncle.color = black
node.grandparent().color = red
tree.insertCase1(node.grandparent())
} else {
tree.insertCase4(node)
}
}
func (tree *Tree) insertCase4(node *Node) {
grandparent := node.grandparent()
if node == node.Parent.Right && node.Parent == grandparent.Left {
tree.rotateLeft(node.Parent)
node = node.Left
} else if node == node.Parent.Left && node.Parent == grandparent.Right {
tree.rotateRight(node.Parent)
node = node.Right
}
tree.insertCase5(node)
}
func (tree *Tree) insertCase5(node *Node) {
node.Parent.color = black
grandparent := node.grandparent()
grandparent.color = red
if node == node.Parent.Left && node.Parent == grandparent.Left {
tree.rotateRight(grandparent)
} else if node == node.Parent.Right && node.Parent == grandparent.Right {
tree.rotateLeft(grandparent)
}
}
func (node *Node) maximumNode() *Node {
if node == nil {
return nil
}
for node.Right != nil {
node = node.Right
}
return node
}
func (tree *Tree) deleteCase1(node *Node) {
if node.Parent == nil {
return
}
tree.deleteCase2(node)
}
func (tree *Tree) deleteCase2(node *Node) {
sibling := node.sibling()
if nodeColor(sibling) == red {
node.Parent.color = red
sibling.color = black
if node == node.Parent.Left {
tree.rotateLeft(node.Parent)
} else {
tree.rotateRight(node.Parent)
}
}
tree.deleteCase3(node)
}
func (tree *Tree) deleteCase3(node *Node) {
sibling := node.sibling()
if nodeColor(node.Parent) == black &&
nodeColor(sibling) == black &&
nodeColor(sibling.Left) == black &&
nodeColor(sibling.Right) == black {
sibling.color = red
tree.deleteCase1(node.Parent)
} else {
tree.deleteCase4(node)
}
}
func (tree *Tree) deleteCase4(node *Node) {
sibling := node.sibling()
if nodeColor(node.Parent) == red &&
nodeColor(sibling) == black &&
nodeColor(sibling.Left) == black &&
nodeColor(sibling.Right) == black {
sibling.color = red
node.Parent.color = black
} else {
tree.deleteCase5(node)
}
}
func (tree *Tree) deleteCase5(node *Node) {
sibling := node.sibling()
if node == node.Parent.Left &&
nodeColor(sibling) == black &&
nodeColor(sibling.Left) == red &&
nodeColor(sibling.Right) == black {
sibling.color = red
sibling.Left.color = black
tree.rotateRight(sibling)
} else if node == node.Parent.Right &&
nodeColor(sibling) == black &&
nodeColor(sibling.Right) == red &&
nodeColor(sibling.Left) == black {
sibling.color = red
sibling.Right.color = black
tree.rotateLeft(sibling)
}
tree.deleteCase6(node)
}
func (tree *Tree) deleteCase6(node *Node) {
sibling := node.sibling()
sibling.color = nodeColor(node.Parent)
node.Parent.color = black
if node == node.Parent.Left && nodeColor(sibling.Right) == red {
sibling.Right.color = black
tree.rotateLeft(node.Parent)
} else if nodeColor(sibling.Left) == red {
sibling.Left.color = black
tree.rotateRight(node.Parent)
}
}
func nodeColor(node *Node) color {
if node == nil {
return black
}
return node.color
}

View file

@ -0,0 +1,742 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package redblacktree
import (
"fmt"
"testing"
)
func TestRedBlackTreePut(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
if actualValue := tree.Size(); actualValue != 7 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "abcdefg"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := tree.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
}
func TestRedBlackTreeRemove(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
tree.Remove(5)
tree.Remove(6)
tree.Remove(7)
tree.Remove(8)
tree.Remove(5)
if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := tree.Size(); actualValue != 4 {
t.Errorf("Got %v expected %v", actualValue, 7)
}
tests2 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
}
for _, test := range tests2 {
actualValue, actualFound := tree.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
tree.Remove(1)
tree.Remove(4)
tree.Remove(2)
tree.Remove(3)
tree.Remove(2)
tree.Remove(2)
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 {
t.Errorf("Got %v expected %v", empty, true)
}
}
func TestRedBlackTreeLeftAndRight(t *testing.T) {
tree := NewWithIntComparator()
if actualValue := tree.Left(); actualValue != nil {
t.Errorf("Got %v expected %v", actualValue, nil)
}
if actualValue := tree.Right(); actualValue != nil {
t.Errorf("Got %v expected %v", actualValue, nil)
}
tree.Put(1, "a")
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x") // overwrite
tree.Put(2, "b")
if actualValue, expectedValue := fmt.Sprintf("%d", tree.Left().Key), "1"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Left().Value), "x"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%d", tree.Right().Key), "7"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Right().Value), "g"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeCeilingAndFloor(t *testing.T) {
tree := NewWithIntComparator()
if node, found := tree.Floor(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
if node, found := tree.Ceiling(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
if node, found := tree.Floor(4); node.Key != 4 || !found {
t.Errorf("Got %v expected %v", node.Key, 4)
}
if node, found := tree.Floor(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
if node, found := tree.Ceiling(4); node.Key != 4 || !found {
t.Errorf("Got %v expected %v", node.Key, 4)
}
if node, found := tree.Ceiling(8); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
}
func TestRedBlackTreeIteratorNextOnEmpty(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty tree")
}
}
func TestRedBlackTreeIteratorPrevOnEmpty(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty tree")
}
}
func TestRedBlackTreeIterator1Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
// │ ┌── 7
// └── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
it := tree.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
switch key {
case count:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator1Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
// │ ┌── 7
// └── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator2Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
switch key {
case count:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator2Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator3Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(1, "a")
it := tree.Iterator()
count := 0
for it.Next() {
count++
key := it.Key()
switch key {
case count:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator3Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(1, "a")
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator4Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(13, 5)
tree.Put(8, 3)
tree.Put(17, 7)
tree.Put(1, 1)
tree.Put(11, 4)
tree.Put(15, 6)
tree.Put(25, 9)
tree.Put(6, 2)
tree.Put(22, 8)
tree.Put(27, 10)
// │ ┌── 27
// │ ┌── 25
// │ │ └── 22
// │ ┌── 17
// │ │ └── 15
// └── 13
// │ ┌── 11
// └── 8
// │ ┌── 6
// └── 1
it := tree.Iterator()
count := 0
for it.Next() {
count++
value := it.Value()
switch value {
case count:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator4Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(13, 5)
tree.Put(8, 3)
tree.Put(17, 7)
tree.Put(1, 1)
tree.Put(11, 4)
tree.Put(15, 6)
tree.Put(25, 9)
tree.Put(6, 2)
tree.Put(22, 8)
tree.Put(27, 10)
// │ ┌── 27
// │ ┌── 25
// │ │ └── 22
// │ ┌── 17
// │ │ └── 15
// └── 13
// │ ┌── 11
// └── 8
// │ ┌── 6
// └── 1
it := tree.Iterator()
count := tree.Size()
for it.Next() {
}
for it.Prev() {
value := it.Value()
switch value {
case count:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
count--
}
if actualValue, expectedValue := count, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIteratorBegin(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.Begin()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
for it.Next() {
}
it.Begin()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.Next()
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestRedBlackTreeIteratorEnd(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.End()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it.End()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.Prev()
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestRedBlackTreeIteratorFirst(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestRedBlackTreeIteratorLast(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestRedBlackTreeSerialization(t *testing.T) {
tree := NewWithStringComparator()
tree.Put("c", "3")
tree.Put("b", "2")
tree.Put("a", "1")
var err error
assert := func() {
if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" {
t.Errorf("Got %v expected %v", actualValue, "[a,b,c]")
}
if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" {
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
}
if err != nil {
t.Errorf("Got error %v", err)
}
}
assert()
json, err := tree.ToJSON()
assert()
err = tree.FromJSON(json)
assert()
}
func benchmarkGet(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Get(n)
}
}
}
func benchmarkPut(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
}
}
func benchmarkRemove(b *testing.B, tree *Tree, size int) {
for i := 0; i < b.N; i++ {
for n := 0; n < size; n++ {
tree.Remove(n)
}
}
}
func BenchmarkRedBlackTreeGet100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreeGet1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreeGet10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreeGet100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkGet(b, tree, size)
}
func BenchmarkRedBlackTreePut100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreePut1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreePut10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreePut100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkPut(b, tree, size)
}
func BenchmarkRedBlackTreeRemove100(b *testing.B) {
b.StopTimer()
size := 100
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkRedBlackTreeRemove1000(b *testing.B) {
b.StopTimer()
size := 1000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkRedBlackTreeRemove10000(b *testing.B) {
b.StopTimer()
size := 10000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}
func BenchmarkRedBlackTreeRemove100000(b *testing.B) {
b.StopTimer()
size := 100000
tree := NewWithIntComparator()
for n := 0; n < size; n++ {
tree.Put(n, struct{}{})
}
b.StartTimer()
benchmarkRemove(b, tree, size)
}

View file

@ -0,0 +1,39 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package redblacktree
import (
"encoding/json"
"github.com/emirpasic/gods/containers"
"github.com/emirpasic/gods/utils"
)
func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Tree)(nil)
var _ containers.JSONDeserializer = (*Tree)(nil)
}
// ToJSON outputs the JSON representation of list's elements.
func (tree *Tree) ToJSON() ([]byte, error) {
elements := make(map[string]interface{})
it := tree.Iterator()
for it.Next() {
elements[utils.ToString(it.Key())] = it.Value()
}
return json.Marshal(&elements)
}
// FromJSON populates list's elements from the input JSON representation.
func (tree *Tree) FromJSON(data []byte) error {
elements := make(map[string]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
tree.Clear()
for key, value := range elements {
tree.Put(key, value)
}
}
return err
}

Some files were not shown because too many files have changed in this diff Show more