pax_global_header00006660000000000000000000000064133515507300014514gustar00rootroot0000000000000052 comment=1615341f118ae12f353cc8a983f35b584342c9b3 gods-1.12.0/000077500000000000000000000000001335155073000125315ustar00rootroot00000000000000gods-1.12.0/.gitignore000066400000000000000000000004201335155073000145150ustar00rootroot00000000000000# 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 .ideagods-1.12.0/.travis.yml000066400000000000000000000001511335155073000146370ustar00rootroot00000000000000language: go go: - 1.1.x - 1.2.x - 1.3.x - 1.4.x - 1.5.x - 1.6.x - 1.7.x - 1.8.x - tip gods-1.12.0/LICENSE000066400000000000000000000041441335155073000135410ustar00rootroot00000000000000Copyright (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 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. gods-1.12.0/README.md000066400000000000000000001330631335155073000140160ustar00rootroot00000000000000[![GoDoc](https://godoc.org/github.com/emirpasic/gods?status.svg)](https://godoc.org/github.com/emirpasic/gods) [![Build Status](https://travis-ci.org/emirpasic/gods.svg)](https://travis-ci.org/emirpasic/gods) [![Go Report Card](https://goreportcard.com/badge/github.com/emirpasic/gods)](https://goreportcard.com/report/github.com/emirpasic/gods) [![PyPI](https://img.shields.io/pypi/l/Django.svg?maxAge=2592000)](https://github.com/emirpasic/gods/blob/master/LICENSE) # GoDS (Go Data Structures) Implementation of various data structures and algorithms in Go. ## Data Structures - [Containers](#containers) - [Lists](#lists) - [ArrayList](#arraylist) - [SinglyLinkedList](#singlylinkedlist) - [DoublyLinkedList](#doublylinkedlist) - [Sets](#sets) - [HashSet](#hashset) - [TreeSet](#treeset) - [LinkedHashSet](#linkedhashset) - [Stacks](#stacks) - [LinkedListStack](#linkedliststack) - [ArrayStack](#arraystack) - [Maps](#maps) - [HashMap](#hashmap) - [TreeMap](#treemap) - [LinkedHashMap](#linkedhashmap) - [HashBidiMap](#hashbidimap) - [TreeBidiMap](#treebidimap) - [Trees](#trees) - [RedBlackTree](#redblacktree) - [AVLTree](#avltree) - [BTree](#btree) - [BinaryHeap](#binaryheap) - [Functions](#functions) - [Comparator](#comparator) - [Iterator](#iterator) - [IteratorWithIndex](#iteratorwithindex) - [IteratorWithKey](#iteratorwithkey) - [ReverseIteratorWithIndex](#reverseiteratorwithindex) - [ReverseIteratorWithKey](#reverseiteratorwithkey) - [Enumerable](#enumerable) - [EnumerableWithIndex](#enumerablewithindex) - [EnumerableWithKey](#enumerablewithkey) - [Serialization](#serialization) - [JSONSerializer](#jsonserializer) - [JSONDeserializer](#jsondeserializer) - [Sort](#sort) - [Container](#container) - [Appendix](#appendix) ## Containers All data structures implement the container interface with the following methods: ```go type Container interface { Empty() bool Size() int Clear() Values() []interface{} } ``` Containers are either ordered or unordered. All ordered containers provide [stateful iterators](#iterator) and some of them allow [enumerable functions](#enumerable). | **Data** | **Structure** | **Ordered** | **[Iterator](#iterator)** | **[Enumerable](#enumerable)** | **Referenced by** | | :--- | :--- | :---: | :---: | :---: | :---: | | [Lists](#lists) | | | [ArrayList](#arraylist) | yes | yes* | yes | index | | | [SinglyLinkedList](#singlylinkedlist) | yes | yes | yes | index | | | [DoublyLinkedList](#doublylinkedlist) | yes | yes* | yes | index | | [Sets](#sets) | | | [HashSet](#hashset) | no | no | no | index | | | [TreeSet](#treeset) | yes | yes* | yes | index | | | [LinkedHashSet](#linkedhashset) | yes | yes* | yes | index | | [Stacks](#stacks) | | | [LinkedListStack](#linkedliststack) | yes | yes | no | index | | | [ArrayStack](#arraystack) | yes | yes* | no | index | | [Maps](#maps) | | | [HashMap](#hashmap) | no | no | no | key | | | [TreeMap](#treemap) | yes | yes* | yes | key | | | [LinkedHashMap](#linkedhashmap) | yes | yes* | yes | key | | | [HashBidiMap](#hashbidimap) | no | no | no | key* | | | [TreeBidiMap](#treebidimap) | yes | yes* | yes | key* | | [Trees](#trees) | | | [RedBlackTree](#redblacktree) | yes | yes* | no | key | | | [AVLTree](#avltree) | yes | yes* | no | key | | | [BTree](#btree) | yes | yes* | no | key | | | [BinaryHeap](#binaryheap) | yes | yes* | no | index | | | | | *reversible | | *bidirectional | ### Lists A list is a data structure that stores values and may have repeated values. Implements [Container](#containers) interface. ```go 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{}) Set(index int, value interface{}) containers.Container // Empty() bool // Size() int // Clear() // Values() []interface{} } ``` #### ArrayList A [list](#lists) backed by a dynamic array that grows and shrinks implicitly. Implements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import ( "github.com/emirpasic/gods/lists/arraylist" "github.com/emirpasic/gods/utils" ) func main() { 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() // [] list.Insert(0, "b") // ["b"] list.Insert(0, "a") // ["a","b"] } ``` #### SinglyLinkedList A [list](#lists) where each element points to the next element in the list. Implements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import ( sll "github.com/emirpasic/gods/lists/singlylinkedlist" "github.com/emirpasic/gods/utils" ) func main() { list := sll.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() // [] list.Insert(0, "b") // ["b"] list.Insert(0, "a") // ["a","b"] } ``` #### DoublyLinkedList A [list](#lists) where each element points to the next and previous elements in the list. Implements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import ( dll "github.com/emirpasic/gods/lists/doublylinkedlist" "github.com/emirpasic/gods/utils" ) func main() { list := dll.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() // [] list.Insert(0, "b") // ["b"] list.Insert(0, "a") // ["a","b"] } ``` ### Sets A set is a data structure that can store elements and has 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 an element for membership in a set. This structure is often used to ensure that no duplicates are present in a container. Implements [Container](#containers) interface. ```go type Set interface { Add(elements ...interface{}) Remove(elements ...interface{}) Contains(elements ...interface{}) bool containers.Container // Empty() bool // Size() int // Clear() // Values() []interface{} } ``` #### HashSet A [set](#sets) backed by a hash table (actually a Go's map). It makes no guarantees as to the iteration order of the set. Implements [Set](#sets), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/sets/hashset" func main() { set := hashset.New() // empty 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 } ``` #### TreeSet A [set](#sets) backed by a [red-black tree](#redblacktree) to keep the elements ordered with respect to the [comparator](#comparator). Implements [Set](#sets), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/sets/treeset" func main() { set := treeset.NewWithIntComparator() // empty (keys are of type int) 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 } ``` #### LinkedHashSet A [set](#sets) that preserves insertion-order. Data structure is backed by a hash table to store values and [doubly-linked list](#doublylinkedlist) to store insertion ordering. Implements [Set](#sets), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/sets/linkedhashset" func main() { set := linkedhashset.New() // empty set.Add(5) // 5 set.Add(4, 4, 3, 2, 1) // 5, 4, 3, 2, 1 (in insertion-order, duplicates ignored) set.Add(4) // 5, 4, 3, 2, 1 (duplicates ignored, insertion-order unchanged) set.Remove(4) // 5, 3, 2, 1 (in insertion-order) set.Remove(2, 3) // 5, 1 (in insertion-order) set.Contains(1) // true set.Contains(1, 5) // true set.Contains(1, 6) // false _ = set.Values() // []int{5, 1} (in insertion-order) set.Clear() // empty set.Empty() // true set.Size() // 0 } ``` ### Stacks A stack that represents a last-in-first-out (LIFO) data structure. The usual push and pop operations are provided, as well as a method to peek at the top item on the stack. Implements [Container](#containers) interface. ```go 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{} } ``` #### LinkedListStack A [stack](#stacks) based on a [linked list](#singlylinkedlist). Implements [Stack](#stacks), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import lls "github.com/emirpasic/gods/stacks/linkedliststack" func main() { 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 } ``` #### ArrayStack A [stack](#stacks) based on a [array list](#arraylist). Implements [Stack](#stacks), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/stacks/arraystack" func main() { 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 } ``` ### Maps A Map is a data structure that maps keys to values. A map cannot contain duplicate keys and each key can map to at most one value. Implements [Container](#containers) interface. ```go 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{} } ``` A BidiMap is an extension to the Map. A bidirectional map (BidiMap), also called a hash bag, is an associative data structure in which the key-value pairs form a one-to-one relation. This relation works in both directions by allow the value to also act as a key to key, e.g. a pair (a,b) thus provides a 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. ```go type BidiMap interface { GetKey(value interface{}) (key interface{}, found bool) Map } ``` #### HashMap A [map](#maps) based on hash tables. Keys are unordered. Implements [Map](#maps), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/maps/hashmap" func main() { 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 } ``` #### TreeMap A [map](#maps) based on [red-black tree](#redblacktree). Keys are ordered ordered with respect to the [comparator](#comparator). Implements [Map](#maps), [IteratorWithKey](#iteratorwithkey), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/maps/treemap" func main() { 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 // Other: m.Min() // Returns the minimum key and its value from map. m.Max() // Returns the maximum key and its value from map. } ``` #### LinkedHashMap A [map](#maps) that preserves insertion-order. It is backed by a hash table to store values and [doubly-linked list](doublylinkedlist) to store ordering. Implements [Map](#maps), [IteratorWithKey](#iteratorwithkey), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/maps/linkedhashmap" func main() { m := linkedhashmap.New() // empty (keys are of type int) m.Put(2, "b") // 2->b m.Put(1, "x") // 2->b, 1->x (insertion-order) m.Put(1, "a") // 2->b, 1->a (insertion-order) _, _ = m.Get(2) // b, true _, _ = m.Get(3) // nil, false _ = m.Values() // []interface {}{"b", "a"} (insertion-order) _ = m.Keys() // []interface {}{2, 1} (insertion-order) m.Remove(1) // 2->b m.Clear() // empty m.Empty() // true m.Size() // 0 } ``` #### HashBidiMap A [map](#maps) based on two hashmaps. Keys are unordered. Implements [BidiMap](#maps), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import "github.com/emirpasic/gods/maps/hashbidimap" func main() { 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 } ``` #### TreeBidiMap A [map](#maps) based on red-black tree. This map 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 (unlike in [HashBidiMap](#hashbidimap)), which can be significant if contained elements are large. Implements [BidiMap](#maps), [IteratorWithKey](#iteratorwithkey), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. ```go package main import ( "github.com/emirpasic/gods/maps/treebidimap" "github.com/emirpasic/gods/utils" ) func main() { 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 } ``` ### Trees A tree is a widely used data data structure that simulates a hierarchical tree structure, with a root value and subtrees of children, represented as a set of linked nodes; thus no cyclic links. Implements [Container](#containers) interface. ```go type Tree interface { containers.Container // Empty() bool // Size() int // Clear() // Values() []interface{} } ``` #### RedBlackTree A red–black [tree](#trees) is a binary search tree with an extra bit of data per node, its color, which can be either red or black. The extra bit of storage ensures an approximately balanced tree by constraining how nodes are colored from any path from the root to the leaf. Thus, it is a data structure which is a type of self-balancing binary search tree. The balancing of the tree is not perfect but it is good enough to allow it to guarantee searching in O(log n) time, where n is the total number of elements in the tree. The insertion and deletion operations, along with the tree rearrangement and recoloring, are also performed in O(log n) time. [Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree) Implements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.

```go package main import ( "fmt" rbt "github.com/emirpasic/gods/trees/redblacktree" ) func main() { 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 // Other: tree.Left() // gets the left-most (min) node tree.Right() // get the right-most (max) node tree.Floor(1) // get the floor node tree.Ceiling(1) // get the ceiling node } ``` Extending the red-black tree's functionality has been demonstrated in the following [example](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended/redblacktreeextended.go). #### AVLTree AVL [tree](#trees) is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Lookup, insertion, and deletion all take O(log n) time in both the average and worst cases, where n is the number of nodes in the tree prior to the operation. Insertions and deletions may require the tree to be rebalanced by one or more tree rotations. AVL trees are often compared with red–black trees because both support the same set of operations and take O(log n) time for the basic operations. For lookup-intensive applications, AVL trees are faster than red–black trees because they are more strictly balanced. [Wikipedia](https://en.wikipedia.org/wiki/AVL_tree) Implements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.


AVL tree with balance factors (green)

```go package main import ( "fmt" avl "github.com/emirpasic/gods/trees/avltree" ) func main() { 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 } ``` #### BTree B-tree is a self-balancing tree data structure that keeps data sorted and allows searches, sequential access, insertions, and deletions in logarithmic time. The B-tree is a generalization of a binary search tree in that a node can have more than two children. 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 k−1 keys. - All leaves appear in the same level Each internal node’s keys act as separation values which divide its subtrees. For example, if an internal node has 3 child nodes (or subtrees) then it must have 2 keys: a1 and a2. All values in the leftmost subtree will be less than a1, all values in the middle subtree will be between a1 and a2, and all values in the rightmost subtree will be greater than a2.[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree) Implements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.

```go package main import ( "fmt" "github.com/emirpasic/gods/trees/btree" ) func main() { 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 } ``` #### BinaryHeap A binary heap is a [tree](#trees) created using a binary tree. It can be seen as a binary tree with two additional constraints: - Shape property: A binary heap is a complete binary tree; that is, all levels of the tree, except possibly the last one (deepest) are fully filled, and, if the last level of the tree is not complete, the nodes of that level are filled from left to right. - Heap property: All nodes are either greater than or equal to or less than or equal to each of its children, according to a comparison predicate defined for the heap. [Wikipedia](http://en.wikipedia.org/wiki/Binary_heap) Implements [Tree](#trees), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.

```go package main import ( "github.com/emirpasic/gods/trees/binaryheap" "github.com/emirpasic/gods/utils" ) func main() { // 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, 3, 1) // 3, 2, 1 (bulk optimized) heap.Values() // 3, 2, 1 } ``` ## Functions Various helper functions used throughout the library. ### Comparator Some data structures (e.g. TreeMap, TreeSet) require a comparator function to automatically keep their elements sorted upon insertion. This comparator is necessary during the initalization. Comparator is defined as: Return values (int): ```go negative , if a < b zero , if a == b positive , if a > b ``` Comparator signature: ```go type Comparator func(a, b interface{}) int ``` All common comparators for builtin types are included in the library: ```go func StringComparator(a, b interface{}) int func IntComparator(a, b interface{}) int func Int8Comparator(a, b interface{}) int func Int16Comparator(a, b interface{}) int func Int32Comparator(a, b interface{}) int func Int64Comparator(a, b interface{}) int func UIntComparator(a, b interface{}) int func UInt8Comparator(a, b interface{}) int func UInt16Comparator(a, b interface{}) int func UInt32Comparator(a, b interface{}) int func UInt64Comparator(a, b interface{}) int func Float32Comparator(a, b interface{}) int func Float64Comparator(a, b interface{}) int func ByteComparator(a, b interface{}) int func RuneComparator(a, b interface{}) int func TimeComparator(a, b interface{}) int ``` Writing custom comparators is easy: ```go package main import ( "fmt" "github.com/emirpasic/gods/sets/treeset" ) type User struct { id int name string } // Custom comparator (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 } } func main() { 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} } ``` ### Iterator All ordered containers have stateful iterators. Typically an iterator is obtained by _Iterator()_ function of an ordered container. Once obtained, iterator's _Next()_ function moves the iterator to the next element and returns true if there was a next element. If there was an element, then element's can be obtained by iterator's _Value()_ function. Depending on the ordering type, it's position can be obtained by iterator's _Index()_ or _Key()_ functions. Some containers even provide reversible iterators, essentially the same, but provide another extra _Prev()_ function that moves the iterator to the previous element and returns true if there was a previous element. Note: it is unsafe to remove elements from container while iterating. #### IteratorWithIndex An [iterator](#iterator) whose elements are referenced by an index. Typical usage: ```go it := list.Iterator() for it.Next() { index, value := it.Index(), it.Value() ... } ``` Other usages: ```go if it.First() { firstIndex, firstValue := it.Index(), it.Value() ... } ``` ```go for it.Begin(); it.Next(); { ... } ``` #### IteratorWithKey An [iterator](#iterator) whose elements are referenced by a key. Typical usage: ```go it := tree.Iterator() for it.Next() { key, value := it.Key(), it.Value() ... } ``` Other usages: ```go if it.First() { firstKey, firstValue := it.Key(), it.Value() ... } ``` ```go for it.Begin(); it.Next(); { ... } ``` #### ReverseIteratorWithIndex An [iterator](#iterator) whose elements are referenced by an index. Provides all functions as [IteratorWithIndex](#iteratorwithindex), but can also be used for reverse iteration. Typical usage of iteration in reverse: ```go it := list.Iterator() for it.End(); it.Prev(); { index, value := it.Index(), it.Value() ... } ``` Other usages: ```go if it.Last() { lastIndex, lastValue := it.Index(), it.Value() ... } ``` #### ReverseIteratorWithKey An [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration. Typical usage of iteration in reverse: ```go it := tree.Iterator() for it.End(); it.Prev(); { key, value := it.Key(), it.Value() ... } ``` Other usages: ```go if it.Last() { lastKey, lastValue := it.Key(), it.Value() ... } ``` ### Enumerable Enumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces. #### EnumerableWithIndex [Enumerable](#enumerable) functions for ordered containers whose values can be fetched by an index. **Each** Calls the given function once for each element, passing that element's index and value. ```go 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. ```go 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. ```go 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. ```go 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. ```go 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. ```go Find(func(index int, value interface{}) bool) (int, interface{})} ``` **Example:** ```go package main 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("]") } func main() { 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 ] } ``` #### EnumerableWithKey Enumerable functions for ordered containers whose values whose elements are key/value pairs. **Each** Calls the given function once for each element, passing that element's key and value. ```go 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. ```go 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. ```go 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. ```go 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. ```go 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. ```go Find(func(key interface{}, value interface{}) bool) (interface{}, interface{}) ``` **Example:** ```go package main 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("}") } func main() { 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 } } ``` ### Serialization All data structures can be serialized (marshalled) and deserialized (unmarshalled). Currently only JSON support is available. #### JSONSerializer Outputs the container into its JSON representation. Typical usage for key-value structures: ```go package main import ( "fmt" "github.com/emirpasic/gods/maps/hashmap" ) func main() { m := hashmap.New() m.Put("a", "1") m.Put("b", "2") m.Put("c", "3") json, err := m.ToJSON() if err != nil { fmt.Println(err) } fmt.Println(string(json)) // {"a":"1","b":"2","c":"3"} ``` Typical usage for value-only structures: ```go package main import ( "fmt" "github.com/emirpasic/gods/lists/arraylist" ) func main() { list := arraylist.New() list.Add("a", "b", "c") json, err := list.ToJSON() if err != nil { fmt.Println(err) } fmt.Println(string(json)) // ["a","b","c"] } ``` #### JSONDeserializer Populates the container with elements from the input JSON representation. Typical usage for key-value structures: ```go package main import ( "fmt" "github.com/emirpasic/gods/maps/hashmap" ) func main() { hm := hashmap.New() json := []byte(`{"a":"1","b":"2"}`) err := hm.FromJSON(json) if err != nil { fmt.Println(err) } fmt.Println(hm) // HashMap map[b:2 a:1] } ``` Typical usage for value-only structures: ```go package main import ( "fmt" "github.com/emirpasic/gods/lists/arraylist" ) func main() { list := arraylist.New() json := []byte(`["a","b"]`) err := list.FromJSON(json) if err != nil { fmt.Println(err) } fmt.Println(list) // ArrayList ["a","b"] } ``` ### Sort Sort is a general purpose sort function. Lists have an in-place _Sort()_ function and all containers can return their sorted elements via _containers.GetSortedValues()_ function. Internally these all use the _utils.Sort()_ method: ```go package main import "github.com/emirpasic/gods/utils" func main() { 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"] } ``` ### Container Container specific operations: ```go // 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{} ``` Usage: ```go package main import ( "github.com/emirpasic/gods/lists/arraylist" "github.com/emirpasic/gods/utils" ) func main() { list := arraylist.New() list.Add(2, 1, 3) values := GetSortedValues(container, utils.StringComparator) // [1, 2, 3] } ``` ## Appendix ### Motivation Collections and data structures found in other languages: Java Collections, C++ Standard Template Library (STL) containers, Qt Containers, Ruby Enumerable etc. ### Goals **Fast algorithms**: - Based on decades of knowledge and experiences of other libraries mentioned above. **Memory efficient algorithms**: - Avoiding to consume memory by using optimal algorithms and data structures for the given set of problems, e.g. red-black tree in case of TreeMap to avoid keeping redundant sorted array of keys in memory. **Easy to use library**: - Well-structured library with minimalistic set of atomic operations from which more complex operations can be crafted. **Stable library**: - Only additions are permitted keeping the library backward compatible. **Solid documentation and examples**: - Learning by example. **Production ready**: - Used in production. **No dependencies**: - No external imports. There is often a tug of war between speed and memory when crafting algorithms. We choose to optimize for speed in most cases within reasonable limits on memory consumption. Thread safety is not a concern of this project, this should be handled at a higher level. ### Testing and Benchmarking This takes a while, so test within sub-packages: `go test -run=NO_TEST -bench . -benchmem -benchtime 1s ./...`

### Contributing Biggest contribution towards this library is to use it and give us feedback for further improvements and additions. For direct contributions, _pull request_ into master branch or ask to become a contributor. Coding style: ```shell # Install tooling and set path: go get github.com/golang/lint/golint go get github.com/fzipp/gocyclo go get github.com/kisielk/errcheck export PATH=$PATH:$GOPATH/bin # Fix errors and warnings: go fmt ./... && gofmt -s -w . && go vet ./... && go get ./... && go test ./... && golint ./... && gocyclo -avg -over 15 . && errcheck ./... ``` ### License This library is distributed under the BSD-style license found in the [LICENSE](https://github.com/emirpasic/gods/blob/master/LICENSE) file. ### Sponsors ## BrowserStack [BrowserStack](https://www.browserstack.com/?ref=webhook) is a cloud-based cross-browser testing tool that enables developers to test their websites across various browsers on different operating systems and mobile devices, without requiring users to install virtual machines, devices or emulators. gods-1.12.0/containers/000077500000000000000000000000001335155073000146765ustar00rootroot00000000000000gods-1.12.0/containers/containers.go000066400000000000000000000021571335155073000173770ustar00rootroot00000000000000// 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 } gods-1.12.0/containers/containers_test.go000066400000000000000000000024771335155073000204430ustar00rootroot00000000000000// 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!") } } } gods-1.12.0/containers/enumerable.go000066400000000000000000000063171335155073000173530ustar00rootroot00000000000000// 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 would appreciate 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{}) } gods-1.12.0/containers/iterator.go000066400000000000000000000110521335155073000170550ustar00rootroot00000000000000// 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 } gods-1.12.0/containers/serialization.go000066400000000000000000000010441335155073000201010ustar00rootroot00000000000000// 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 } gods-1.12.0/examples/000077500000000000000000000000001335155073000143475ustar00rootroot00000000000000gods-1.12.0/examples/README.md000066400000000000000000000045671335155073000156420ustar00rootroot00000000000000# GoDS (Go Data Structures) Various examples on how to use data structures. ## Examples - [ArrayList](https://github.com/emirpasic/gods/blob/master/examples/arraylist/arraylist.go) - [ArrayStack](https://github.com/emirpasic/gods/blob/master/examples/arraystack/arraystack.go) - [AVLTree](https://github.com/emirpasic/gods/blob/master/examples/avltree/avltree.go) - [BinaryHeap](https://github.com/emirpasic/gods/blob/master/examples/binaryheap/binaryheap.go) - [BTree](https://github.com/emirpasic/gods/blob/master/examples/btree/btree.go) - [Custom Comparator](https://github.com/emirpasic/gods/blob/master/examples/customcomparator/customcomparator.go) - [DoublyLinkedList](https://github.com/emirpasic/gods/blob/master/examples/doublylinkedlist/doublylinkedlist.go) - [EnumerableWithIndex](https://github.com/emirpasic/gods/blob/master/examples/enumerablewithindex/enumerablewithindex.go) - [EnumerableWithKey](https://github.com/emirpasic/gods/blob/master/examples/enumerablewithkey/enumerablewithkey.go) - [HashBidiMap](https://github.com/emirpasic/gods/blob/master/examples/hashbidimap/hashbidimap.go) - [HashMap](https://github.com/emirpasic/gods/blob/master/examples/hashmap/hashmap.go) - [HashSet](https://github.com/emirpasic/gods/blob/master/examples/hashset/hashset.go) - [IteratorWithIndex](https://github.com/emirpasic/gods/blob/master/examples/iteratorwithindex/iteratorwithindex.go) - [iteratorwithkey](https://github.com/emirpasic/gods/blob/master/examples/iteratorwithkey/iteratorwithkey.go) - [IteratorWithKey](https://github.com/emirpasic/gods/blob/master/examples/linkedliststack/linkedliststack.go) - [RedBlackTree](https://github.com/emirpasic/gods/blob/master/examples/redblacktree/redblacktree.go) - [RedBlackTreeExtended](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended/redblacktreeextended.go) - [Serialization](https://github.com/emirpasic/gods/blob/master/examples/serialization/serialization.go) - [SinglyLinkedList](https://github.com/emirpasic/gods/blob/master/examples/singlylinkedlist/singlylinkedlist.go) - [Sort](https://github.com/emirpasic/gods/blob/master/examples/sort/sort.go) - [TreeBidiMap](https://github.com/emirpasic/gods/blob/master/examples/treebidimap/treebidimap.go) - [TreeMap](https://github.com/emirpasic/gods/blob/master/examples/treemap/treemap.go) - [TreeSet](https://github.com/emirpasic/gods/blob/master/examples/treeset/treeset.go) gods-1.12.0/examples/arraylist/000077500000000000000000000000001335155073000163615ustar00rootroot00000000000000gods-1.12.0/examples/arraylist/arraylist.go000066400000000000000000000022151335155073000207220ustar00rootroot00000000000000// 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 main import ( "github.com/emirpasic/gods/lists/arraylist" "github.com/emirpasic/gods/utils" ) // ArrayListExample to demonstrate basic usage of ArrayList func main() { 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() // [] } gods-1.12.0/examples/arraystack/000077500000000000000000000000001335155073000165135ustar00rootroot00000000000000gods-1.12.0/examples/arraystack/arraystack.go000066400000000000000000000013741335155073000212130ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/stacks/arraystack" // ArrayStackExample to demonstrate basic usage of ArrayStack func main() { 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 } gods-1.12.0/examples/avltree/000077500000000000000000000000001335155073000160115ustar00rootroot00000000000000gods-1.12.0/examples/avltree/avltree.go000066400000000000000000000024661335155073000200120ustar00rootroot00000000000000// 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 main import ( "fmt" avl "github.com/emirpasic/gods/trees/avltree" ) // AVLTreeExample to demonstrate basic usage of AVLTree func main() { 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 } gods-1.12.0/examples/binaryheap/000077500000000000000000000000001335155073000164715ustar00rootroot00000000000000gods-1.12.0/examples/binaryheap/binaryheap.go000066400000000000000000000027651335155073000211540ustar00rootroot00000000000000// 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 main import ( "github.com/emirpasic/gods/trees/binaryheap" "github.com/emirpasic/gods/utils" ) // BinaryHeapExample to demonstrate basic usage of BinaryHeap func main() { // 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 } gods-1.12.0/examples/btree/000077500000000000000000000000001335155073000154505ustar00rootroot00000000000000gods-1.12.0/examples/btree/btree.go000066400000000000000000000032061335155073000171010ustar00rootroot00000000000000// 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 main import ( "fmt" "github.com/emirpasic/gods/trees/btree" ) // BTreeExample to demonstrate basic usage of BTree func main() { 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 } gods-1.12.0/examples/customcomparator/000077500000000000000000000000001335155073000177515ustar00rootroot00000000000000gods-1.12.0/examples/customcomparator/customcomparator.go000066400000000000000000000015561335155073000237110ustar00rootroot00000000000000// 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 main 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 main() { 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} } gods-1.12.0/examples/doublylinkedlist/000077500000000000000000000000001335155073000177305ustar00rootroot00000000000000gods-1.12.0/examples/doublylinkedlist/doublylinkedlist.go000066400000000000000000000022551335155073000236440ustar00rootroot00000000000000// 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 main import ( dll "github.com/emirpasic/gods/lists/doublylinkedlist" "github.com/emirpasic/gods/utils" ) // DoublyLinkedListExample to demonstrate basic usage of DoublyLinkedList func main() { 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() // [] } gods-1.12.0/examples/enumerablewithindex/000077500000000000000000000000001335155073000204125ustar00rootroot00000000000000gods-1.12.0/examples/enumerablewithindex/enumerablewithindex.go000066400000000000000000000033621335155073000250100ustar00rootroot00000000000000// 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 main 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 main() { 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 ] } gods-1.12.0/examples/enumerablewithkey/000077500000000000000000000000001335155073000200735ustar00rootroot00000000000000gods-1.12.0/examples/enumerablewithkey/enumerablewithkey.go000066400000000000000000000040331335155073000241460ustar00rootroot00000000000000// 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 main 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 main() { 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 } } gods-1.12.0/examples/hashbidimap/000077500000000000000000000000001335155073000166205ustar00rootroot00000000000000gods-1.12.0/examples/hashbidimap/hashbidimap.go000066400000000000000000000015741335155073000214270ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/maps/hashbidimap" // HashBidiMapExample to demonstrate basic usage of HashMap func main() { 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 } gods-1.12.0/examples/hashmap/000077500000000000000000000000001335155073000157705ustar00rootroot00000000000000gods-1.12.0/examples/hashmap/hashmap.go000066400000000000000000000013551335155073000177440ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/maps/hashmap" // HashMapExample to demonstrate basic usage of HashMap func main() { 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 } gods-1.12.0/examples/hashset/000077500000000000000000000000001335155073000160065ustar00rootroot00000000000000gods-1.12.0/examples/hashset/hashset.go000066400000000000000000000014411335155073000177740ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/sets/hashset" // HashSetExample to demonstrate basic usage of HashSet func main() { 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 } gods-1.12.0/examples/iteratorwithindex/000077500000000000000000000000001335155073000201245ustar00rootroot00000000000000gods-1.12.0/examples/iteratorwithindex/iteratorwithindex.go000066400000000000000000000025331335155073000242330ustar00rootroot00000000000000// 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 main import ( "fmt" "github.com/emirpasic/gods/sets/treeset" ) // IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex func main() { 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 } } gods-1.12.0/examples/iteratorwithkey/000077500000000000000000000000001335155073000176055ustar00rootroot00000000000000gods-1.12.0/examples/iteratorwithkey/iteratorwithkey.go000066400000000000000000000025111335155073000233710ustar00rootroot00000000000000// 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 main import ( "fmt" "github.com/emirpasic/gods/maps/treemap" ) // IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey func main() { 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 } } gods-1.12.0/examples/linkedhashmap/000077500000000000000000000000001335155073000171575ustar00rootroot00000000000000gods-1.12.0/examples/linkedhashmap/linkedhashmap.go000066400000000000000000000015601335155073000223200ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/maps/linkedhashmap" // LinkedHashMapExample to demonstrate basic usage of LinkedHashMapExample func main() { m := linkedhashmap.New() // empty (keys are of type int) m.Put(2, "b") // 2->b m.Put(1, "x") // 2->b, 1->x (insertion-order) m.Put(1, "a") // 2->b, 1->a (insertion-order) _, _ = m.Get(2) // b, true _, _ = m.Get(3) // nil, false _ = m.Values() // []interface {}{"b", "a"} (insertion-order) _ = m.Keys() // []interface {}{2, 1} (insertion-order) m.Remove(1) // 2->b m.Clear() // empty m.Empty() // true m.Size() // 0 } gods-1.12.0/examples/linkedhashset/000077500000000000000000000000001335155073000171755ustar00rootroot00000000000000gods-1.12.0/examples/linkedhashset/linkedhashset.go000066400000000000000000000015451335155073000223570ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/sets/linkedhashset" // LinkedHashSetExample to demonstrate basic usage of LinkedHashSet func main() { set := linkedhashset.New() // empty set.Add(5) // 5 set.Add(4, 4, 3, 2, 1) // 5, 4, 3, 2, 1 (in insertion-order, duplicates ignored) set.Remove(4) // 5, 3, 2, 1 (in insertion-order) set.Remove(2, 3) // 5, 1 (in insertion-order) set.Contains(1) // true set.Contains(1, 5) // true set.Contains(1, 6) // false _ = set.Values() // []int{5, 1} (in insertion-order) set.Clear() // empty set.Empty() // true set.Size() // 0 } gods-1.12.0/examples/linkedliststack/000077500000000000000000000000001335155073000175375ustar00rootroot00000000000000gods-1.12.0/examples/linkedliststack/linkedliststack.go000066400000000000000000000013071335155073000232570ustar00rootroot00000000000000// 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 main import lls "github.com/emirpasic/gods/stacks/linkedliststack" // LinkedListStackExample to demonstrate basic usage of LinkedListStack func main() { 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 } gods-1.12.0/examples/redblacktree/000077500000000000000000000000001335155073000167765ustar00rootroot00000000000000gods-1.12.0/examples/redblacktree/redblacktree.go000066400000000000000000000025321335155073000217560ustar00rootroot00000000000000// 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 main import ( "fmt" rbt "github.com/emirpasic/gods/trees/redblacktree" ) // RedBlackTreeExample to demonstrate basic usage of RedBlackTree func main() { 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 } gods-1.12.0/examples/redblacktreeextended/000077500000000000000000000000001335155073000205175ustar00rootroot00000000000000gods-1.12.0/examples/redblacktreeextended/redblacktreeextended.go000066400000000000000000000056411335155073000252240ustar00rootroot00000000000000// 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 redblacktreeextended 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 main() { 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 } gods-1.12.0/examples/serialization/000077500000000000000000000000001335155073000172245ustar00rootroot00000000000000gods-1.12.0/examples/serialization/serialization.go000066400000000000000000000022151335155073000224300ustar00rootroot00000000000000package serialization 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"} } gods-1.12.0/examples/singlylinkedlist/000077500000000000000000000000001335155073000177375ustar00rootroot00000000000000gods-1.12.0/examples/singlylinkedlist/singlylinkedlist.go000066400000000000000000000022551335155073000236620ustar00rootroot00000000000000// 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 main import ( sll "github.com/emirpasic/gods/lists/singlylinkedlist" "github.com/emirpasic/gods/utils" ) // SinglyLinkedListExample to demonstrate basic usage of SinglyLinkedList func main() { 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() // [] } gods-1.12.0/examples/sort/000077500000000000000000000000001335155073000153365ustar00rootroot00000000000000gods-1.12.0/examples/sort/sort.go000066400000000000000000000012031335155073000166500ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/utils" // SortExample to demonstrate basic usage of basic sort func main() { 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"] } gods-1.12.0/examples/treebidimap/000077500000000000000000000000001335155073000166345ustar00rootroot00000000000000gods-1.12.0/examples/treebidimap/treebidimap.go000066400000000000000000000016331335155073000214530ustar00rootroot00000000000000// 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 main import ( "github.com/emirpasic/gods/maps/treebidimap" "github.com/emirpasic/gods/utils" ) // TreeBidiMapExample to demonstrate basic usage of TreeBidiMap func main() { 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 } gods-1.12.0/examples/treemap/000077500000000000000000000000001335155073000160045ustar00rootroot00000000000000gods-1.12.0/examples/treemap/treemap.go000066400000000000000000000016771335155073000200030ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/maps/treemap" // TreeMapExample to demonstrate basic usage of TreeMap func main() { 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 } gods-1.12.0/examples/treeset/000077500000000000000000000000001335155073000160225ustar00rootroot00000000000000gods-1.12.0/examples/treeset/treeset.go000066400000000000000000000016561335155073000200340ustar00rootroot00000000000000// 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 main import "github.com/emirpasic/gods/sets/treeset" // TreeSetExample to demonstrate basic usage of TreeSet func main() { 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 } gods-1.12.0/lists/000077500000000000000000000000001335155073000136675ustar00rootroot00000000000000gods-1.12.0/lists/arraylist/000077500000000000000000000000001335155073000157015ustar00rootroot00000000000000gods-1.12.0/lists/arraylist/arraylist.go000066400000000000000000000134201335155073000202420ustar00rootroot00000000000000// 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" "strings" "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" ) 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 list and adds the passed values, if any, to the list func New(values ...interface{}) *List { list := &List{} if len(values) > 0 { list.Add(values...) } 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 the element at the given index from the list. 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 } //IndexOf returns index of provided element func (list *List) IndexOf(value interface{}) int { if list.size == 0 { return -1 } for index, element := range list.elements { if element == value { return index } } return -1 } // 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 copy(list.elements[index+l:], list.elements[index:list.size-l]) copy(list.elements[index:], values) } // Set the value at specified index // 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) Set(index int, value interface{}) { if !list.withinRange(index) { // Append if index == list.size { list.Add(value) } return } list.elements[index] = 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) } } gods-1.12.0/lists/arraylist/arraylist_test.go000066400000000000000000000416751335155073000213160ustar00rootroot00000000000000// 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 TestListNew(t *testing.T) { list1 := New() if actualValue := list1.Empty(); actualValue != true { t.Errorf("Got %v expected %v", actualValue, true) } list2 := New(1, "b") if actualValue := list2.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } if actualValue, ok := list2.Get(0); actualValue != 1 || !ok { t.Errorf("Got %v expected %v", actualValue, 1) } if actualValue, ok := list2.Get(1); actualValue != "b" || !ok { t.Errorf("Got %v expected %v", actualValue, "b") } if actualValue, ok := list2.Get(2); actualValue != nil || ok { t.Errorf("Got %v expected %v", actualValue, nil) } } 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 TestListIndexOf(t *testing.T) { list := New() expectedIndex := -1 if index := list.IndexOf("a"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } list.Add("a") list.Add("b", "c") expectedIndex = 0 if index := list.IndexOf("a"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } expectedIndex = 1 if index := list.IndexOf("b"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } expectedIndex = 2 if index := list.IndexOf("c"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } } 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 TestListSet(t *testing.T) { list := New() list.Set(0, "a") list.Set(1, "b") if actualValue := list.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } list.Set(2, "c") // append if actualValue := list.Size(); actualValue != 3 { t.Errorf("Got %v expected %v", actualValue, 3) } list.Set(4, "d") // ignore list.Set(1, "bb") // update if actualValue := list.Size(); actualValue != 3 { t.Errorf("Got %v expected %v", actualValue, 3) } if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; 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) } gods-1.12.0/lists/arraylist/enumerable.go000066400000000000000000000046141335155073000203540ustar00rootroot00000000000000// 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 } gods-1.12.0/lists/arraylist/iterator.go000066400000000000000000000055351335155073000200710ustar00rootroot00000000000000// 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() } gods-1.12.0/lists/arraylist/serialization.go000066400000000000000000000014211335155073000211030ustar00rootroot00000000000000// 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 } gods-1.12.0/lists/doublylinkedlist/000077500000000000000000000000001335155073000172505ustar00rootroot00000000000000gods-1.12.0/lists/doublylinkedlist/doublylinkedlist.go000066400000000000000000000203661335155073000231670ustar00rootroot00000000000000// 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" "strings" "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" ) 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 list and adds the passed values, if any, to the list func New(values ...interface{}) *List { list := &List{} if len(values) > 0 { list.Add(values...) } 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 the element at the given index from the list. 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 } //IndexOf returns index of provided element func (list *List) IndexOf(value interface{}) int { if list.size == 0 { return -1 } for index, element := range list.Values() { if element == value { return index } } return -1 } // 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 } } // Set value at specified index position // 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) Set(index int, value interface{}) { if !list.withinRange(index) { // Append if index == list.size { list.Add(value) } return } 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; { fmt.Println("Set last", index, value, foundElement, foundElement.prev) e, foundElement = e-1, foundElement.prev } } else { foundElement = list.first for e := 0; e != index; { e, foundElement = e+1, foundElement.next } } foundElement.value = value } // 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 } gods-1.12.0/lists/doublylinkedlist/doublylinkedlist_test.go000066400000000000000000000424511335155073000242250ustar00rootroot00000000000000// 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" "testing" "github.com/emirpasic/gods/utils" ) func TestListNew(t *testing.T) { list1 := New() if actualValue := list1.Empty(); actualValue != true { t.Errorf("Got %v expected %v", actualValue, true) } list2 := New(1, "b") if actualValue := list2.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } if actualValue, ok := list2.Get(0); actualValue != 1 || !ok { t.Errorf("Got %v expected %v", actualValue, 1) } if actualValue, ok := list2.Get(1); actualValue != "b" || !ok { t.Errorf("Got %v expected %v", actualValue, "b") } if actualValue, ok := list2.Get(2); actualValue != nil || ok { t.Errorf("Got %v expected %v", actualValue, nil) } } 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 TestListIndexOf(t *testing.T) { list := New() expectedIndex := -1 if index := list.IndexOf("a"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } list.Add("a") list.Add("b", "c") expectedIndex = 0 if index := list.IndexOf("a"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } expectedIndex = 1 if index := list.IndexOf("b"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } expectedIndex = 2 if index := list.IndexOf("c"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } } 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 TestListSet(t *testing.T) { list := New() list.Set(0, "a") list.Set(1, "b") if actualValue := list.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } list.Set(2, "c") // append if actualValue := list.Size(); actualValue != 3 { t.Errorf("Got %v expected %v", actualValue, 3) } list.Set(4, "d") // ignore list.Set(1, "bb") // update if actualValue := list.Size(); actualValue != 3 { t.Errorf("Got %v expected %v", actualValue, 3) } if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } list.Set(2, "cc") // last to first traversal list.Set(0, "aa") // first to last traversal if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "aabbcc"; 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) } gods-1.12.0/lists/doublylinkedlist/enumerable.go000066400000000000000000000046351335155073000217260ustar00rootroot00000000000000// 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 } gods-1.12.0/lists/doublylinkedlist/iterator.go000066400000000000000000000065221335155073000214350ustar00rootroot00000000000000// 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() } gods-1.12.0/lists/doublylinkedlist/serialization.go000066400000000000000000000014521335155073000224560ustar00rootroot00000000000000// 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 } gods-1.12.0/lists/lists.go000066400000000000000000000024211335155073000153530ustar00rootroot00000000000000// 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{}) Set(index int, value interface{}) containers.Container // Empty() bool // Size() int // Clear() // Values() []interface{} } gods-1.12.0/lists/singlylinkedlist/000077500000000000000000000000001335155073000172575ustar00rootroot00000000000000gods-1.12.0/lists/singlylinkedlist/enumerable.go000066400000000000000000000046351335155073000217350ustar00rootroot00000000000000// 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 } gods-1.12.0/lists/singlylinkedlist/iterator.go000066400000000000000000000042261335155073000214430ustar00rootroot00000000000000// 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() } gods-1.12.0/lists/singlylinkedlist/serialization.go000066400000000000000000000014521335155073000224650ustar00rootroot00000000000000// 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 } gods-1.12.0/lists/singlylinkedlist/singlylinkedlist.go000066400000000000000000000156571335155073000232140ustar00rootroot00000000000000// 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" "strings" "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" ) 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 list and adds the passed values, if any, to the list func New(values ...interface{}) *List { list := &List{} if len(values) > 0 { list.Add(values...) } 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 the element at the given index from the list. 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 } //IndexOf returns index of provided element func (list *List) IndexOf(value interface{}) int { if list.size == 0 { return -1 } for index, element := range list.Values() { if element == value { return index } } return -1 } // 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 } } // Set value at specified index // 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) Set(index int, value interface{}) { if !list.withinRange(index) { // Append if index == list.size { list.Add(value) } return } foundElement := list.first for e := 0; e != index; { e, foundElement = e+1, foundElement.next } foundElement.value = value } // 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 } gods-1.12.0/lists/singlylinkedlist/singlylinkedlist_test.go000066400000000000000000000356621335155073000242510ustar00rootroot00000000000000// 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" "testing" "github.com/emirpasic/gods/utils" ) func TestListNew(t *testing.T) { list1 := New() if actualValue := list1.Empty(); actualValue != true { t.Errorf("Got %v expected %v", actualValue, true) } list2 := New(1, "b") if actualValue := list2.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } if actualValue, ok := list2.Get(0); actualValue != 1 || !ok { t.Errorf("Got %v expected %v", actualValue, 1) } if actualValue, ok := list2.Get(1); actualValue != "b" || !ok { t.Errorf("Got %v expected %v", actualValue, "b") } if actualValue, ok := list2.Get(2); actualValue != nil || ok { t.Errorf("Got %v expected %v", actualValue, nil) } } 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 TestListIndexOf(t *testing.T) { list := New() expectedIndex := -1 if index := list.IndexOf("a"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } list.Add("a") list.Add("b", "c") expectedIndex = 0 if index := list.IndexOf("a"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } expectedIndex = 1 if index := list.IndexOf("b"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } expectedIndex = 2 if index := list.IndexOf("c"); index != expectedIndex { t.Errorf("Got %v expected %v", index, expectedIndex) } } 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 TestListSet(t *testing.T) { list := New() list.Set(0, "a") list.Set(1, "b") if actualValue := list.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } list.Set(2, "c") // append if actualValue := list.Size(); actualValue != 3 { t.Errorf("Got %v expected %v", actualValue, 3) } list.Set(4, "d") // ignore list.Set(1, "bb") // update if actualValue := list.Size(); actualValue != 3 { t.Errorf("Got %v expected %v", actualValue, 3) } if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; 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) } gods-1.12.0/maps/000077500000000000000000000000001335155073000134715ustar00rootroot00000000000000gods-1.12.0/maps/hashbidimap/000077500000000000000000000000001335155073000157425ustar00rootroot00000000000000gods-1.12.0/maps/hashbidimap/hashbidimap.go000066400000000000000000000057001335155073000205440ustar00rootroot00000000000000// 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 } gods-1.12.0/maps/hashbidimap/hashbidimap_test.go000066400000000000000000000161471335155073000216120ustar00rootroot00000000000000// 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) } gods-1.12.0/maps/hashbidimap/serialization.go000066400000000000000000000014651335155073000211540ustar00rootroot00000000000000// 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 the map. func (m *Map) ToJSON() ([]byte, error) { return m.forwardMap.ToJSON() } // FromJSON populates the map 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 } gods-1.12.0/maps/hashmap/000077500000000000000000000000001335155073000151125ustar00rootroot00000000000000gods-1.12.0/maps/hashmap/hashmap.go000066400000000000000000000040611335155073000170630ustar00rootroot00000000000000// 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 } gods-1.12.0/maps/hashmap/hashmap_test.go000066400000000000000000000150731335155073000201270ustar00rootroot00000000000000// 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) } gods-1.12.0/maps/hashmap/serialization.go000066400000000000000000000017111335155073000203160ustar00rootroot00000000000000// 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 the map. 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 the map 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 } gods-1.12.0/maps/linkedhashmap/000077500000000000000000000000001335155073000163015ustar00rootroot00000000000000gods-1.12.0/maps/linkedhashmap/enumerable.go000066400000000000000000000047041335155073000207540ustar00rootroot00000000000000// 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 linkedhashmap 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 := New() 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 := New() 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 } gods-1.12.0/maps/linkedhashmap/iterator.go000066400000000000000000000055071335155073000204700ustar00rootroot00000000000000// 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 linkedhashmap import ( "github.com/emirpasic/gods/containers" "github.com/emirpasic/gods/lists/doublylinkedlist" ) func assertIteratorImplementation() { var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) } // Iterator holding the iterator's state type Iterator struct { iterator doublylinkedlist.Iterator table map[interface{}]interface{} } // Iterator returns a stateful iterator whose elements are key/value pairs. func (m *Map) Iterator() Iterator { return Iterator{ iterator: m.ordering.Iterator(), table: m.table} } // 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{} { key := iterator.iterator.Value() return iterator.table[key] } // Key returns the current element's key. // Does not modify the state of the iterator. func (iterator *Iterator) Key() interface{} { return iterator.iterator.Value() } // 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() } gods-1.12.0/maps/linkedhashmap/linkedhashmap.go000066400000000000000000000054351335155073000214470ustar00rootroot00000000000000// 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 linkedhashmap is a map that preserves insertion-order. // // It is backed by a hash table to store values and doubly-linked list to store ordering. // // Structure is not thread safe. // // Reference: http://en.wikipedia.org/wiki/Associative_array package linkedhashmap import ( "fmt" "github.com/emirpasic/gods/lists/doublylinkedlist" "github.com/emirpasic/gods/maps" "strings" ) func assertMapImplementation() { var _ maps.Map = (*Map)(nil) } // Map holds the elements in a red-black tree type Map struct { table map[interface{}]interface{} ordering *doublylinkedlist.List } // New instantiates a linked-hash-map. func New() *Map { return &Map{ table: make(map[interface{}]interface{}), ordering: doublylinkedlist.New(), } } // 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{}) { if _, contains := m.table[key]; !contains { m.ordering.Append(key) } m.table[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) { value = m.table[key] found = value != nil return } // 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{}) { if _, contains := m.table[key]; contains { delete(m.table, key) index := m.ordering.IndexOf(key) m.ordering.Remove(index) } } // 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.ordering.Size() } // Keys returns all keys in-order func (m *Map) Keys() []interface{} { return m.ordering.Values() } // Values returns all values in-order based on the key. func (m *Map) Values() []interface{} { values := make([]interface{}, m.Size()) count := 0 it := m.Iterator() for it.Next() { values[count] = it.Value() count++ } return values } // Clear removes all elements from the map. func (m *Map) Clear() { m.table = make(map[interface{}]interface{}) m.ordering.Clear() } // String returns a string representation of container func (m *Map) String() string { str := "LinkedHashMap\nmap[" it := m.Iterator() for it.Next() { str += fmt.Sprintf("%v:%v ", it.Key(), it.Value()) } return strings.TrimRight(str, " ") + "]" } gods-1.12.0/maps/linkedhashmap/linkedhashmap_test.go000066400000000000000000000361441335155073000225070ustar00rootroot00000000000000// 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 linkedhashmap 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{}{5, 6, 7, 3, 4, 1, 2}; !sameElements(actualValue, expectedValue) { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := m.Values(), []interface{}{"e", "f", "g", "c", "d", "a", "b"}; !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{}{3, 4, 1, 2}; !sameElements(actualValue, expectedValue) { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := m.Values(), []interface{}{"c", "d", "a", "b"}; !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 one is nil, the other must also be nil. if (a == nil) != (b == nil) { return false } if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } func TestMapEach(t *testing.T) { m := New() m.Put("c", 1) m.Put("a", 2) m.Put("b", 3) 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, "c"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 2: if actualValue, expectedValue := key, "a"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 3: if actualValue, expectedValue := key, "b"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } default: t.Errorf("Too many") } }) } func TestMapMap(t *testing.T) { m := New() 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("c"); actualValue != 9 { t.Errorf("Got %v expected %v", actualValue, "mapped: c") } 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 mappedMap.Size() != 3 { t.Errorf("Got %v expected %v", mappedMap.Size(), 3) } } func TestMapSelect(t *testing.T) { m := New() m.Put("c", 3) m.Put("b", 1) m.Put("a", 2) selectedMap := m.Select(func(key interface{}, value interface{}) bool { return key.(string) >= "a" && key.(string) <= "b" }) if actualValue, _ := selectedMap.Get("b"); actualValue != 1 { t.Errorf("Got %v expected %v", actualValue, "value: a") } if actualValue, _ := selectedMap.Get("a"); 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 := New() 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 := New() 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 := New() 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 := New() 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 := New() it := m.Iterator() it = m.Iterator() for it.Next() { t.Errorf("Shouldn't iterate on empty map") } } func TestMapIteratorPrevOnEmpty(t *testing.T) { m := New() it := m.Iterator() it = m.Iterator() for it.Prev() { t.Errorf("Shouldn't iterate on empty map") } } func TestMapIteratorNext(t *testing.T) { m := New() m.Put("c", 1) m.Put("a", 2) m.Put("b", 3) it := m.Iterator() count := 0 for it.Next() { count++ key := it.Key() value := it.Value() switch key { case "c": if actualValue, expectedValue := value, 1; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case "a": if actualValue, expectedValue := value, 2; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case "b": 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 := New() m.Put("c", 1) m.Put("a", 2) m.Put("b", 3) it := m.Iterator() for it.Next() { } countDown := m.Size() for it.Prev() { key := it.Key() value := it.Value() switch key { case "c": if actualValue, expectedValue := value, 1; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case "a": if actualValue, expectedValue := value, 2; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case "b": 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 := New() 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 != 3 || value != "c" { t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") } } func TestMapTreeIteratorEnd(t *testing.T) { m := New() 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 != 2 || value != "b" { t.Errorf("Got %v,%v expected %v,%v", key, value, 2, "b") } } func TestMapIteratorFirst(t *testing.T) { m := New() 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 != 3 || value != "c" { t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") } } func TestMapIteratorLast(t *testing.T) { m := New() 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 != 2 || value != "b" { t.Errorf("Got %v,%v expected %v,%v", key, value, 2, "b") } } func TestMapSerialization(t *testing.T) { for i := 0; i < 10; i++ { original := New() original.Put("d", "4") original.Put("e", "5") original.Put("c", "3") original.Put("b", "2") original.Put("a", "1") assertSerialization(original, "A", t) serialized, err := original.ToJSON() if err != nil { t.Errorf("Got error %v", err) } assertSerialization(original, "B", t) deserialized := New() err = deserialized.FromJSON(serialized) if err != nil { t.Errorf("Got error %v", err) } assertSerialization(deserialized, "C", t) } } //noinspection GoBoolExpressions func assertSerialization(m *Map, txt string, t *testing.T) { if actualValue := m.Keys(); false || actualValue[0].(string) != "d" || actualValue[1].(string) != "e" || actualValue[2].(string) != "c" || actualValue[3].(string) != "b" || actualValue[4].(string) != "a" { t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[d,e,c,b,a]") } if actualValue := m.Values(); false || actualValue[0].(string) != "4" || actualValue[1].(string) != "5" || actualValue[2].(string) != "3" || actualValue[3].(string) != "2" || actualValue[4].(string) != "1" { t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[4,5,3,2,1]") } if actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue { t.Errorf("[%s] Got %v expected %v", txt, actualValue, expectedValue) } } 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 := New() 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 := New() 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 := New() 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 := New() 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 := New() b.StartTimer() benchmarkPut(b, m, size) } func BenchmarkTreeMapPut1000(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 BenchmarkTreeMapPut10000(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 BenchmarkTreeMapPut100000(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 BenchmarkTreeMapRemove100(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 BenchmarkTreeMapRemove1000(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 BenchmarkTreeMapRemove10000(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 BenchmarkTreeMapRemove100000(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) } gods-1.12.0/maps/linkedhashmap/serialization.go000066400000000000000000000037251335155073000215140ustar00rootroot00000000000000// 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 linkedhashmap import ( "bytes" "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 map. func (m *Map) ToJSON() ([]byte, error) { var b []byte buf := bytes.NewBuffer(b) buf.WriteRune('{') it := m.Iterator() lastIndex := m.Size() - 1 index := 0 for it.Next() { km, err := json.Marshal(it.Key()) if err != nil { return nil, err } buf.Write(km) buf.WriteRune(':') vm, err := json.Marshal(it.Value()) if err != nil { return nil, err } buf.Write(vm) if index != lastIndex { buf.WriteRune(',') } index++ } buf.WriteRune('}') return buf.Bytes(), nil } // FromJSON populates map 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 //} // FromJSON populates map 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 { return err } index := make(map[string]int) var keys []interface{} for key := range elements { keys = append(keys, key) esc, _ := json.Marshal(key) index[key] = bytes.Index(data, esc) } byIndex := func(a, b interface{}) int { key1 := a.(string) key2 := b.(string) index1 := index[key1] index2 := index[key2] return index1 - index2 } utils.Sort(keys, byIndex) m.Clear() for _, key := range keys { m.Put(key, elements[key.(string)]) } return nil } gods-1.12.0/maps/maps.go000066400000000000000000000024071335155073000147630ustar00rootroot00000000000000// 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 } gods-1.12.0/maps/treebidimap/000077500000000000000000000000001335155073000157565ustar00rootroot00000000000000gods-1.12.0/maps/treebidimap/enumerable.go000066400000000000000000000050161335155073000204260ustar00rootroot00000000000000// 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 } gods-1.12.0/maps/treebidimap/iterator.go000066400000000000000000000053541335155073000201450ustar00rootroot00000000000000// 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() } gods-1.12.0/maps/treebidimap/serialization.go000066400000000000000000000017361335155073000211710ustar00rootroot00000000000000// 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 the map. 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 the map 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 } gods-1.12.0/maps/treebidimap/treebidimap.go000066400000000000000000000104421335155073000205730ustar00rootroot00000000000000// 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, " ") + "]" } gods-1.12.0/maps/treebidimap/treebidimap_test.go000066400000000000000000000413751335155073000216430ustar00rootroot00000000000000// 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) { for i := 0; i < 10; i++ { original := NewWith(utils.StringComparator, utils.StringComparator) original.Put("d", "4") original.Put("e", "5") original.Put("c", "3") original.Put("b", "2") original.Put("a", "1") assertSerialization(original, "A", t) serialized, err := original.ToJSON() if err != nil { t.Errorf("Got error %v", err) } assertSerialization(original, "B", t) deserialized := NewWith(utils.StringComparator, utils.StringComparator) err = deserialized.FromJSON(serialized) if err != nil { t.Errorf("Got error %v", err) } assertSerialization(deserialized, "C", t) } } //noinspection GoBoolExpressions func assertSerialization(m *Map, txt string, t *testing.T) { if actualValue := m.Keys(); false || actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" || actualValue[3].(string) != "d" || actualValue[4].(string) != "e" { t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[a,b,c,d,e]") } if actualValue := m.Values(); false || actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" || actualValue[3].(string) != "4" || actualValue[4].(string) != "5" { t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[1,2,3,4,5]") } if actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue { t.Errorf("[%s] Got %v expected %v", txt, actualValue, expectedValue) } } 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) } gods-1.12.0/maps/treemap/000077500000000000000000000000001335155073000151265ustar00rootroot00000000000000gods-1.12.0/maps/treemap/enumerable.go000066400000000000000000000051011335155073000175710ustar00rootroot00000000000000// 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 } gods-1.12.0/maps/treemap/iterator.go000066400000000000000000000053241335155073000173120ustar00rootroot00000000000000// 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() } gods-1.12.0/maps/treemap/serialization.go000066400000000000000000000011671335155073000203370ustar00rootroot00000000000000// 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 the map. func (m *Map) ToJSON() ([]byte, error) { return m.tree.ToJSON() } // FromJSON populates the map from the input JSON representation. func (m *Map) FromJSON(data []byte) error { return m.tree.FromJSON(data) } gods-1.12.0/maps/treemap/treemap.go000066400000000000000000000112021335155073000171060ustar00rootroot00000000000000// 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 } // Floor finds the floor key-value pair for the input key. // In case that no floor is found, then both returned values will be nil. // It's generally enough to check the first value (key) for nil, which determines if floor was found. // // Floor key is defined as the largest key that is smaller than or equal to the given key. // A floor key may not be found, either because the map is empty, or because // all keys in the map are larger than the given key. // // Key should adhere to the comparator's type assertion, otherwise method panics. func (m *Map) Floor(key interface{}) (foundKey interface{}, foundValue interface{}) { node, found := m.tree.Floor(key) if found { return node.Key, node.Value } return nil, nil } // Ceiling finds the ceiling key-value pair for the input key. // In case that no ceiling is found, then both returned values will be nil. // It's generally enough to check the first value (key) for nil, which determines if ceiling was found. // // Ceiling key is defined as the smallest key that is larger than or equal to the given key. // A ceiling key may not be found, either because the map is empty, or because // all keys in the map are smaller than the given key. // // Key should adhere to the comparator's type assertion, otherwise method panics. func (m *Map) Ceiling(key interface{}) (foundKey interface{}, foundValue interface{}) { node, found := m.tree.Ceiling(key) if found { 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, " ") + "]" } gods-1.12.0/maps/treemap/treemap_test.go000066400000000000000000000420511335155073000201530ustar00rootroot00000000000000// 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 TestMapFloor(t *testing.T) { m := NewWithIntComparator() m.Put(7, "g") m.Put(3, "c") m.Put(1, "a") // key,expectedKey,expectedValue,expectedFound tests1 := [][]interface{}{ {-1, nil, nil, false}, {0, nil, nil, false}, {1, 1, "a", true}, {2, 1, "a", true}, {3, 3, "c", true}, {4, 3, "c", true}, {7, 7, "g", true}, {8, 7, "g", true}, } for _, test := range tests1 { // retrievals actualKey, actualValue := m.Floor(test[0]) actualFound := actualKey != nil && actualValue != nil if actualKey != test[1] || actualValue != test[2] || actualFound != test[3] { t.Errorf("Got %v, %v, %v, expected %v, %v, %v", actualKey, actualValue, actualFound, test[1], test[2], test[3]) } } } func TestMapCeiling(t *testing.T) { m := NewWithIntComparator() m.Put(7, "g") m.Put(3, "c") m.Put(1, "a") // key,expectedKey,expectedValue,expectedFound tests1 := [][]interface{}{ {-1, 1, "a", true}, {0, 1, "a", true}, {1, 1, "a", true}, {2, 3, "c", true}, {3, 3, "c", true}, {4, 7, "g", true}, {7, 7, "g", true}, {8, nil, nil, false}, } for _, test := range tests1 { // retrievals actualKey, actualValue := m.Ceiling(test[0]) actualFound := actualKey != nil && actualValue != nil if actualKey != test[1] || actualValue != test[2] || actualFound != test[3] { t.Errorf("Got %v, %v, %v, expected %v, %v, %v", actualKey, actualValue, actualFound, test[1], test[2], test[3]) } } } 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) { for i := 0; i < 10; i++ { original := NewWithStringComparator() original.Put("d", "4") original.Put("e", "5") original.Put("c", "3") original.Put("b", "2") original.Put("a", "1") assertSerialization(original, "A", t) serialized, err := original.ToJSON() if err != nil { t.Errorf("Got error %v", err) } assertSerialization(original, "B", t) deserialized := NewWithStringComparator() err = deserialized.FromJSON(serialized) if err != nil { t.Errorf("Got error %v", err) } assertSerialization(deserialized, "C", t) } } //noinspection GoBoolExpressions func assertSerialization(m *Map, txt string, t *testing.T) { if actualValue := m.Keys(); false || actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" || actualValue[3].(string) != "d" || actualValue[4].(string) != "e" { t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[a,b,c,d,e]") } if actualValue := m.Values(); false || actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" || actualValue[3].(string) != "4" || actualValue[4].(string) != "5" { t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[1,2,3,4,5]") } if actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue { t.Errorf("[%s] Got %v expected %v", txt, actualValue, expectedValue) } } 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) } gods-1.12.0/sets/000077500000000000000000000000001335155073000135075ustar00rootroot00000000000000gods-1.12.0/sets/hashset/000077500000000000000000000000001335155073000151465ustar00rootroot00000000000000gods-1.12.0/sets/hashset/hashset.go000066400000000000000000000045121335155073000171360ustar00rootroot00000000000000// 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 and adds the passed values, if any, to the set func New(values ...interface{}) *Set { set := &Set{items: make(map[interface{}]struct{})} if len(values) > 0 { set.Add(values...) } return set } // 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 } gods-1.12.0/sets/hashset/hashset_test.go000066400000000000000000000121221335155073000201710ustar00rootroot00000000000000// 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 TestSetNew(t *testing.T) { set := New(2, 1) if actualValue := set.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } if actualValue := set.Contains(1); actualValue != true { t.Errorf("Got %v expected %v", actualValue, true) } if actualValue := set.Contains(2); actualValue != true { t.Errorf("Got %v expected %v", actualValue, true) } if actualValue := set.Contains(3); actualValue != false { t.Errorf("Got %v expected %v", actualValue, true) } } 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) } gods-1.12.0/sets/hashset/serialization.go000066400000000000000000000014101335155073000203460ustar00rootroot00000000000000// 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 the set. func (set *Set) ToJSON() ([]byte, error) { return json.Marshal(set.Values()) } // FromJSON populates the set 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 } gods-1.12.0/sets/linkedhashset/000077500000000000000000000000001335155073000163355ustar00rootroot00000000000000gods-1.12.0/sets/linkedhashset/enumerable.go000066400000000000000000000045571335155073000210160ustar00rootroot00000000000000// 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 linkedhashset import "github.com/emirpasic/gods/containers" 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 := New() 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 := New() 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 } gods-1.12.0/sets/linkedhashset/iterator.go000066400000000000000000000054071335155073000205230ustar00rootroot00000000000000// 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 linkedhashset import ( "github.com/emirpasic/gods/containers" "github.com/emirpasic/gods/lists/doublylinkedlist" ) func assertIteratorImplementation() { var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) } // Iterator holding the iterator's state type Iterator struct { iterator doublylinkedlist.Iterator } // Iterator returns a stateful iterator whose values can be fetched by an index. func (set *Set) Iterator() Iterator { return Iterator{iterator: set.ordering.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 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 { 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 { 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() } // Index returns the current element's index. // Does not modify the state of the iterator. func (iterator *Iterator) Index() int { return iterator.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.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 index and value can be retrieved by Index() 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 index and value can be retrieved by Index() and Value(). // Modifies the state of the iterator. func (iterator *Iterator) Last() bool { return iterator.iterator.Last() } gods-1.12.0/sets/linkedhashset/linkedhashset.go000066400000000000000000000060201335155073000215100ustar00rootroot00000000000000// 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 linkedhashset is a set that preserves insertion-order. // // It is backed by a hash table to store values and doubly-linked list to store ordering. // // Note that insertion-order is not affected if an element is re-inserted into the set. // // Structure is not thread safe. // // References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29 package linkedhashset import ( "fmt" "github.com/emirpasic/gods/lists/doublylinkedlist" "github.com/emirpasic/gods/sets" "strings" ) func assertSetImplementation() { var _ sets.Set = (*Set)(nil) } // Set holds elements in go's native map type Set struct { table map[interface{}]struct{} ordering *doublylinkedlist.List } var itemExists = struct{}{} // New instantiates a new empty set and adds the passed values, if any, to the set func New(values ...interface{}) *Set { set := &Set{ table: make(map[interface{}]struct{}), ordering: doublylinkedlist.New(), } if len(values) > 0 { set.Add(values...) } return set } // Add adds the items (one or more) to the set. // Note that insertion-order is not affected if an element is re-inserted into the set. func (set *Set) Add(items ...interface{}) { for _, item := range items { if _, contains := set.table[item]; !contains { set.table[item] = itemExists set.ordering.Append(item) } } } // Remove removes the items (one or more) from the set. // Slow operation, worst-case O(n^2). func (set *Set) Remove(items ...interface{}) { for _, item := range items { if _, contains := set.table[item]; contains { delete(set.table, item) index := set.ordering.IndexOf(item) set.ordering.Remove(index) } } } // 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.table[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 set.ordering.Size() } // Clear clears all values in the set. func (set *Set) Clear() { set.table = make(map[interface{}]struct{}) set.ordering.Clear() } // Values returns all items in the set. func (set *Set) Values() []interface{} { values := make([]interface{}, set.Size()) it := set.Iterator() for it.Next() { values[it.Index()] = it.Value() } return values } // String returns a string representation of container func (set *Set) String() string { str := "LinkedHashSet\n" items := []string{} it := set.Iterator() for it.Next() { items = append(items, fmt.Sprintf("%v", it.Value())) } str += strings.Join(items, ", ") return str } gods-1.12.0/sets/linkedhashset/linkedhashset_test.go000066400000000000000000000302451335155073000225550ustar00rootroot00000000000000// 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 linkedhashset import ( "fmt" "testing" ) func TestSetNew(t *testing.T) { set := New(2, 1) if actualValue := set.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } values := set.Values() if actualValue := values[0]; actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } if actualValue := values[1]; actualValue != 1 { t.Errorf("Got %v expected %v", actualValue, 1) } } 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 TestSetEach(t *testing.T) { set := New() set.Add("c", "a", "b") set.Each(func(index int, value interface{}) { 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, "a"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 2: if actualValue, expectedValue := value, "b"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } default: t.Errorf("Too many") } }) } func TestSetMap(t *testing.T) { set := New() set.Add("c", "a", "b") mappedSet := set.Map(func(index int, value interface{}) interface{} { return "mapped: " + value.(string) }) if actualValue, expectedValue := mappedSet.Contains("mapped: c", "mapped: b", "mapped: a"), true; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := mappedSet.Contains("mapped: c", "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 := New() 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 := New() 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 := New() 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 := New() set.Add("c", "a", "b") foundIndex, foundValue := set.Find(func(index int, value interface{}) bool { return value.(string) == "c" }) if foundValue != "c" || foundIndex != 0 { t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 0) } 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 := New() set.Add("c", "a", "b") } func TestSetIteratorPrevOnEmpty(t *testing.T) { set := New() it := set.Iterator() for it.Prev() { t.Errorf("Shouldn't iterate on empty set") } } func TestSetIteratorNext(t *testing.T) { set := New() 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, "c"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 1: if actualValue, expectedValue := value, "a"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 2: if actualValue, expectedValue := value, "b"; 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 := New() 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, "c"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 1: if actualValue, expectedValue := value, "a"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } case 2: if actualValue, expectedValue := value, "b"; 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) { set := New() it := set.Iterator() it.Begin() set.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 := New() 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 := New() 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 := New() 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 != 2 || value != "c" { t.Errorf("Got %v,%v expected %v,%v", index, value, 3, "c") } } 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) } gods-1.12.0/sets/linkedhashset/serialization.go000066400000000000000000000014161335155073000215430ustar00rootroot00000000000000// 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 linkedhashset 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 the set. func (set *Set) ToJSON() ([]byte, error) { return json.Marshal(set.Values()) } // FromJSON populates the set 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 } gods-1.12.0/sets/sets.go000066400000000000000000000016571335155073000150250ustar00rootroot00000000000000// 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{} } gods-1.12.0/sets/treeset/000077500000000000000000000000001335155073000151625ustar00rootroot00000000000000gods-1.12.0/sets/treeset/enumerable.go000066400000000000000000000047601335155073000176370ustar00rootroot00000000000000// 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 } gods-1.12.0/sets/treeset/iterator.go000066400000000000000000000057351335155073000173540ustar00rootroot00000000000000// 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.Prev() } gods-1.12.0/sets/treeset/serialization.go000066400000000000000000000014101335155073000203620ustar00rootroot00000000000000// 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 the set. func (set *Set) ToJSON() ([]byte, error) { return json.Marshal(set.Values()) } // FromJSON populates the set 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 } gods-1.12.0/sets/treeset/treeset.go000066400000000000000000000055241335155073000171720ustar00rootroot00000000000000// 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, values ...interface{}) *Set { set := &Set{tree: rbt.NewWith(comparator)} if len(values) > 0 { set.Add(values...) } return set } // NewWithIntComparator instantiates a new empty set with the IntComparator, i.e. keys are of type int. func NewWithIntComparator(values ...interface{}) *Set { set := &Set{tree: rbt.NewWithIntComparator()} if len(values) > 0 { set.Add(values...) } return set } // NewWithStringComparator instantiates a new empty set with the StringComparator, i.e. keys are of type string. func NewWithStringComparator(values ...interface{}) *Set { set := &Set{tree: rbt.NewWithStringComparator()} if len(values) > 0 { set.Add(values...) } return set } // 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 } gods-1.12.0/sets/treeset/treeset_test.go000066400000000000000000000320351335155073000202260ustar00rootroot00000000000000// 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 TestSetNew(t *testing.T) { set := NewWithIntComparator(2, 1) if actualValue := set.Size(); actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } values := set.Values() if actualValue := values[0]; actualValue != 1 { t.Errorf("Got %v expected %v", actualValue, 1) } if actualValue := values[1]; actualValue != 2 { t.Errorf("Got %v expected %v", actualValue, 2) } } 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) { set := NewWithStringComparator() it := set.Iterator() it.Begin() set.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 != 2 || value != "c" { t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "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) } gods-1.12.0/stacks/000077500000000000000000000000001335155073000140215ustar00rootroot00000000000000gods-1.12.0/stacks/arraystack/000077500000000000000000000000001335155073000161655ustar00rootroot00000000000000gods-1.12.0/stacks/arraystack/arraystack.go000066400000000000000000000047671335155073000206760ustar00rootroot00000000000000// 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() } gods-1.12.0/stacks/arraystack/arraystack_test.go000066400000000000000000000211301335155073000217140ustar00rootroot00000000000000// 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) } gods-1.12.0/stacks/arraystack/iterator.go000066400000000000000000000057351335155073000203570ustar00rootroot00000000000000// 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() } gods-1.12.0/stacks/arraystack/serialization.go000066400000000000000000000012261335155073000213720ustar00rootroot00000000000000// 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 the stack. func (stack *Stack) ToJSON() ([]byte, error) { return stack.list.ToJSON() } // FromJSON populates the stack from the input JSON representation. func (stack *Stack) FromJSON(data []byte) error { return stack.list.FromJSON(data) } gods-1.12.0/stacks/linkedliststack/000077500000000000000000000000001335155073000172115ustar00rootroot00000000000000gods-1.12.0/stacks/linkedliststack/iterator.go000066400000000000000000000040211335155073000213660ustar00rootroot00000000000000// 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() } gods-1.12.0/stacks/linkedliststack/linkedliststack.go000066400000000000000000000045321335155073000227340ustar00rootroot00000000000000// 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() } gods-1.12.0/stacks/linkedliststack/linkedliststack_test.go000066400000000000000000000146411335155073000237750ustar00rootroot00000000000000// 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) } gods-1.12.0/stacks/linkedliststack/serialization.go000066400000000000000000000012331335155073000224140ustar00rootroot00000000000000// 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 the stack. func (stack *Stack) ToJSON() ([]byte, error) { return stack.list.ToJSON() } // FromJSON populates the stack from the input JSON representation. func (stack *Stack) FromJSON(data []byte) error { return stack.list.FromJSON(data) } gods-1.12.0/stacks/stacks.go000066400000000000000000000020671335155073000156450ustar00rootroot00000000000000// 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{} } gods-1.12.0/trees/000077500000000000000000000000001335155073000136535ustar00rootroot00000000000000gods-1.12.0/trees/avltree/000077500000000000000000000000001335155073000153155ustar00rootroot00000000000000gods-1.12.0/trees/avltree/avltree.go000066400000000000000000000217051335155073000173130ustar00rootroot00000000000000// 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) } } gods-1.12.0/trees/avltree/avltree_test.go000066400000000000000000000440231335155073000203500ustar00rootroot00000000000000// 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, "") } if node, found := tree.Ceiling(0); node != nil || found { t.Errorf("Got %v expected %v", node, "") } 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, "") } 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, "") } } 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) } gods-1.12.0/trees/avltree/iterator.go000066400000000000000000000067241335155073000175060ustar00rootroot00000000000000// 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() } gods-1.12.0/trees/avltree/serialization.go000066400000000000000000000017571335155073000205330ustar00rootroot00000000000000// 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 the tree. 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 the tree 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 } gods-1.12.0/trees/binaryheap/000077500000000000000000000000001335155073000157755ustar00rootroot00000000000000gods-1.12.0/trees/binaryheap/binaryheap.go000066400000000000000000000115641335155073000204550ustar00rootroot00000000000000// 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() } gods-1.12.0/trees/binaryheap/binaryheap_test.go000066400000000000000000000235661335155073000215210ustar00rootroot00000000000000// 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) } gods-1.12.0/trees/binaryheap/iterator.go000066400000000000000000000056351335155073000201660ustar00rootroot00000000000000// 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() } gods-1.12.0/trees/binaryheap/serialization.go000066400000000000000000000012141335155073000211770ustar00rootroot00000000000000// 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 the heap. func (heap *Heap) ToJSON() ([]byte, error) { return heap.list.ToJSON() } // FromJSON populates the heap from the input JSON representation. func (heap *Heap) FromJSON(data []byte) error { return heap.list.FromJSON(data) } gods-1.12.0/trees/btree/000077500000000000000000000000001335155073000147545ustar00rootroot00000000000000gods-1.12.0/trees/btree/btree.go000066400000000000000000000414551335155073000164150ustar00rootroot00000000000000// 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 k−1 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] } gods-1.12.0/trees/btree/btree_test.go000066400000000000000000001115641335155073000174530ustar00rootroot00000000000000// 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 ( "fmt" "testing" ) func TestBTreeGet1(t *testing.T) { tree := NewWithIntComparator(3) tree.Put(1, "a") tree.Put(2, "b") tree.Put(3, "c") tree.Put(4, "d") tree.Put(5, "e") tree.Put(6, "f") tree.Put(7, "g") tests := [][]interface{}{ {0, nil, false}, {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 tests { if value, found := tree.Get(test[0]); value != test[1] || found != test[2] { t.Errorf("Got %v,%v expected %v,%v", value, found, test[1], test[2]) } } } func TestBTreeGet2(t *testing.T) { tree := NewWithIntComparator(3) tree.Put(7, "g") tree.Put(9, "i") tree.Put(10, "j") tree.Put(6, "f") tree.Put(3, "c") tree.Put(4, "d") tree.Put(5, "e") tree.Put(8, "h") tree.Put(2, "b") tree.Put(1, "a") tests := [][]interface{}{ {0, nil, false}, {1, "a", true}, {2, "b", true}, {3, "c", true}, {4, "d", true}, {5, "e", true}, {6, "f", true}, {7, "g", true}, {8, "h", true}, {9, "i", true}, {10, "j", true}, {11, nil, false}, } for _, test := range tests { if value, found := tree.Get(test[0]); value != test[1] || found != test[2] { t.Errorf("Got %v,%v expected %v,%v", value, found, test[1], test[2]) } } } func TestBTreePut1(t *testing.T) { // https://upload.wikimedia.org/wikipedia/commons/3/33/B_tree_insertion_example.png tree := NewWithIntComparator(3) assertValidTree(t, tree, 0) tree.Put(1, 0) assertValidTree(t, tree, 1) assertValidTreeNode(t, tree.Root, 1, 0, []int{1}, false) tree.Put(2, 1) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false) tree.Put(3, 2) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) tree.Put(4, 2) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true) tree.Put(5, 2) assertValidTree(t, tree, 5) assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{5}, true) tree.Put(6, 2) assertValidTree(t, tree, 6) assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true) tree.Put(7, 2) assertValidTree(t, tree, 7) assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) } func TestBTreePut2(t *testing.T) { tree := NewWithIntComparator(4) assertValidTree(t, tree, 0) tree.Put(0, 0) assertValidTree(t, tree, 1) assertValidTreeNode(t, tree.Root, 1, 0, []int{0}, false) tree.Put(2, 2) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{0, 2}, false) tree.Put(1, 1) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false) tree.Put(1, 1) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false) tree.Put(3, 3) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{2, 3}, true) tree.Put(4, 4) assertValidTree(t, tree, 5) assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{2, 3, 4}, true) tree.Put(5, 5) assertValidTree(t, tree, 6) assertValidTreeNode(t, tree.Root, 2, 3, []int{1, 3}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{4, 5}, true) } func TestBTreePut3(t *testing.T) { // http://www.geeksforgeeks.org/b-tree-set-1-insert-2/ tree := NewWithIntComparator(6) assertValidTree(t, tree, 0) tree.Put(10, 0) assertValidTree(t, tree, 1) assertValidTreeNode(t, tree.Root, 1, 0, []int{10}, false) tree.Put(20, 1) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{10, 20}, false) tree.Put(30, 2) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 3, 0, []int{10, 20, 30}, false) tree.Put(40, 3) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 4, 0, []int{10, 20, 30, 40}, false) tree.Put(50, 4) assertValidTree(t, tree, 5) assertValidTreeNode(t, tree.Root, 5, 0, []int{10, 20, 30, 40, 50}, false) tree.Put(60, 5) assertValidTree(t, tree, 6) assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{40, 50, 60}, true) tree.Put(70, 6) assertValidTree(t, tree, 7) assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) assertValidTreeNode(t, tree.Root.Children[1], 4, 0, []int{40, 50, 60, 70}, true) tree.Put(80, 7) assertValidTree(t, tree, 8) assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) assertValidTreeNode(t, tree.Root.Children[1], 5, 0, []int{40, 50, 60, 70, 80}, true) tree.Put(90, 8) assertValidTree(t, tree, 9) assertValidTreeNode(t, tree.Root, 2, 3, []int{30, 60}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{40, 50}, true) assertValidTreeNode(t, tree.Root.Children[2], 3, 0, []int{70, 80, 90}, true) } func TestBTreePut4(t *testing.T) { tree := NewWithIntComparator(3) assertValidTree(t, tree, 0) tree.Put(6, nil) assertValidTree(t, tree, 1) assertValidTreeNode(t, tree.Root, 1, 0, []int{6}, false) tree.Put(5, nil) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{5, 6}, false) tree.Put(4, nil) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true) tree.Put(3, nil) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{3, 4}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true) tree.Put(2, nil) assertValidTree(t, tree, 5) assertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true) tree.Put(1, nil) assertValidTree(t, tree, 6) assertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{1, 2}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true) tree.Put(0, nil) assertValidTree(t, tree, 7) assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) tree.Put(-1, nil) assertValidTree(t, tree, 8) assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-1, 0}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) tree.Put(-2, nil) assertValidTree(t, tree, 9) assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 3, []int{-1, 1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{-2}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[2], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) tree.Put(-3, nil) assertValidTree(t, tree, 10) assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 3, []int{-1, 1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-3, -2}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[2], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) tree.Put(-4, nil) assertValidTree(t, tree, 11) assertValidTreeNode(t, tree.Root, 2, 3, []int{-1, 3}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{-3}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[2], 1, 2, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{-4}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{-2}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[2].Children[0], 1, 0, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[2].Children[1], 1, 0, []int{6}, true) } func TestBTreeRemove1(t *testing.T) { // empty tree := NewWithIntComparator(3) tree.Remove(1) assertValidTree(t, tree, 0) } func TestBTreeRemove2(t *testing.T) { // leaf node (no underflow) tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Remove(1) assertValidTree(t, tree, 1) assertValidTreeNode(t, tree.Root, 1, 0, []int{2}, false) tree.Remove(2) assertValidTree(t, tree, 0) } func TestBTreeRemove3(t *testing.T) { // merge with right (underflow) { tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Remove(1) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{2, 3}, false) } // merge with left (underflow) { tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Remove(3) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false) } } func TestBTreeRemove4(t *testing.T) { // rotate left (underflow) tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Put(4, nil) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true) tree.Remove(1) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true) } func TestBTreeRemove5(t *testing.T) { // rotate right (underflow) tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Put(0, nil) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{0, 1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) tree.Remove(3) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true) } func TestBTreeRemove6(t *testing.T) { // root height reduction after a series of underflows on right side // use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Put(4, nil) tree.Put(5, nil) tree.Put(6, nil) tree.Put(7, nil) assertValidTree(t, tree, 7) assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) tree.Remove(7) assertValidTree(t, tree, 6) assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true) } func TestBTreeRemove7(t *testing.T) { // root height reduction after a series of underflows on left side // use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Put(4, nil) tree.Put(5, nil) tree.Put(6, nil) tree.Put(7, nil) assertValidTree(t, tree, 7) assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) tree.Remove(1) // series of underflows assertValidTree(t, tree, 6) assertValidTreeNode(t, tree.Root, 2, 3, []int{4, 6}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{2, 3}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{7}, true) // clear all remaining tree.Remove(2) assertValidTree(t, tree, 5) assertValidTreeNode(t, tree.Root, 2, 3, []int{4, 6}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{7}, true) tree.Remove(3) assertValidTree(t, tree, 4) assertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false) assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{4, 5}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{7}, true) tree.Remove(4) assertValidTree(t, tree, 3) assertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{7}, true) tree.Remove(5) assertValidTree(t, tree, 2) assertValidTreeNode(t, tree.Root, 2, 0, []int{6, 7}, false) tree.Remove(6) assertValidTree(t, tree, 1) assertValidTreeNode(t, tree.Root, 1, 0, []int{7}, false) tree.Remove(7) assertValidTree(t, tree, 0) } func TestBTreeRemove8(t *testing.T) { // use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html tree := NewWithIntComparator(3) tree.Put(1, nil) tree.Put(2, nil) tree.Put(3, nil) tree.Put(4, nil) tree.Put(5, nil) tree.Put(6, nil) tree.Put(7, nil) tree.Put(8, nil) tree.Put(9, nil) assertValidTree(t, tree, 9) assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) assertValidTreeNode(t, tree.Root.Children[1], 2, 3, []int{6, 8}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[2], 1, 0, []int{9}, true) tree.Remove(1) assertValidTree(t, tree, 8) assertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false) assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{4}, true) assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{8}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{2, 3}, true) assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{5}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{7}, true) assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{9}, true) } func TestBTreeRemove9(t *testing.T) { const max = 1000 orders := []int{3, 4, 5, 6, 7, 8, 9, 10, 20, 100, 500, 1000, 5000, 10000} for _, order := range orders { tree := NewWithIntComparator(order) { for i := 1; i <= max; i++ { tree.Put(i, i) } assertValidTree(t, tree, max) for i := 1; i <= max; i++ { if _, found := tree.Get(i); !found { t.Errorf("Not found %v", i) } } for i := 1; i <= max; i++ { tree.Remove(i) } assertValidTree(t, tree, 0) } { for i := max; i > 0; i-- { tree.Put(i, i) } assertValidTree(t, tree, max) for i := max; i > 0; i-- { if _, found := tree.Get(i); !found { t.Errorf("Not found %v", i) } } for i := max; i > 0; i-- { tree.Remove(i) } assertValidTree(t, tree, 0) } } } func TestBTreeHeight(t *testing.T) { tree := NewWithIntComparator(3) if actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(1, 0) if actualValue, expectedValue := tree.Height(), 1; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(2, 1) if actualValue, expectedValue := tree.Height(), 1; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(3, 2) if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(4, 2) if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(5, 2) if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(6, 2) if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Put(7, 2) if actualValue, expectedValue := tree.Height(), 3; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } tree.Remove(1) tree.Remove(2) tree.Remove(3) tree.Remove(4) tree.Remove(5) tree.Remove(6) tree.Remove(7) if actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } func TestBTreeLeftAndRight(t *testing.T) { tree := NewWithIntComparator(3) 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 := tree.LeftKey(), 1; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := tree.LeftValue(), "x"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := tree.RightKey(), 7; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := tree.RightValue(), "g"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } func TestBTreeIteratorValuesAndKeys(t *testing.T) { tree := NewWithIntComparator(4) tree.Put(4, "d") tree.Put(5, "e") tree.Put(6, "f") tree.Put(3, "c") tree.Put(1, "a") tree.Put(7, "g") tree.Put(2, "b") tree.Put(1, "x") // override 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()...), "xbcdefg"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue := tree.Size(); actualValue != 7 { t.Errorf("Got %v expected %v", actualValue, 7) } } func TestBTreeIteratorNextOnEmpty(t *testing.T) { tree := NewWithIntComparator(3) it := tree.Iterator() for it.Next() { t.Errorf("Shouldn't iterate on empty tree") } } func TestBTreeIteratorPrevOnEmpty(t *testing.T) { tree := NewWithIntComparator(3) it := tree.Iterator() for it.Prev() { t.Errorf("Shouldn't iterate on empty tree") } } func TestBTreeIterator1Next(t *testing.T) { tree := NewWithIntComparator(3) 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 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 TestBTreeIterator1Prev(t *testing.T) { tree := NewWithIntComparator(3) 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 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 TestBTreeIterator2Next(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIterator2Prev(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIterator3Next(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIterator3Prev(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIterator4Next(t *testing.T) { tree := NewWithIntComparator(3) 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) 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 TestBTreeIterator4Prev(t *testing.T) { tree := NewWithIntComparator(3) 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) 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 TestBTreeIteratorBegin(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIteratorEnd(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIteratorFirst(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTreeIteratorLast(t *testing.T) { tree := NewWithIntComparator(3) 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 TestBTree_search(t *testing.T) { { tree := NewWithIntComparator(3) tree.Root = &Node{Entries: []*Entry{}, Children: make([]*Node, 0)} tests := [][]interface{}{ {0, 0, false}, } for _, test := range tests { index, found := tree.search(tree.Root, test[0]) if actualValue, expectedValue := index, test[1]; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := found, test[2]; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } } { tree := NewWithIntComparator(3) tree.Root = &Node{Entries: []*Entry{{2, 0}, {4, 1}, {6, 2}}, Children: []*Node{}} tests := [][]interface{}{ {0, 0, false}, {1, 0, false}, {2, 0, true}, {3, 1, false}, {4, 1, true}, {5, 2, false}, {6, 2, true}, {7, 3, false}, } for _, test := range tests { index, found := tree.search(tree.Root, test[0]) if actualValue, expectedValue := index, test[1]; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue, expectedValue := found, test[2]; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } } } func assertValidTree(t *testing.T, tree *Tree, expectedSize int) { if actualValue, expectedValue := tree.size, expectedSize; actualValue != expectedValue { t.Errorf("Got %v expected %v for tree size", actualValue, expectedValue) } } func assertValidTreeNode(t *testing.T, node *Node, expectedEntries int, expectedChildren int, keys []int, hasParent bool) { if actualValue, expectedValue := node.Parent != nil, hasParent; actualValue != expectedValue { t.Errorf("Got %v expected %v for hasParent", actualValue, expectedValue) } if actualValue, expectedValue := len(node.Entries), expectedEntries; actualValue != expectedValue { t.Errorf("Got %v expected %v for entries size", actualValue, expectedValue) } if actualValue, expectedValue := len(node.Children), expectedChildren; actualValue != expectedValue { t.Errorf("Got %v expected %v for children size", actualValue, expectedValue) } for i, key := range keys { if actualValue, expectedValue := node.Entries[i].Key, key; actualValue != expectedValue { t.Errorf("Got %v expected %v for key", actualValue, expectedValue) } } } func TestBTreeSerialization(t *testing.T) { tree := NewWithStringComparator(3) 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 BenchmarkBTreeGet100(b *testing.B) { b.StopTimer() size := 100 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkGet(b, tree, size) } func BenchmarkBTreeGet1000(b *testing.B) { b.StopTimer() size := 1000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkGet(b, tree, size) } func BenchmarkBTreeGet10000(b *testing.B) { b.StopTimer() size := 10000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkGet(b, tree, size) } func BenchmarkBTreeGet100000(b *testing.B) { b.StopTimer() size := 100000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkGet(b, tree, size) } func BenchmarkBTreePut100(b *testing.B) { b.StopTimer() size := 100 tree := NewWithIntComparator(128) b.StartTimer() benchmarkPut(b, tree, size) } func BenchmarkBTreePut1000(b *testing.B) { b.StopTimer() size := 1000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkPut(b, tree, size) } func BenchmarkBTreePut10000(b *testing.B) { b.StopTimer() size := 10000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkPut(b, tree, size) } func BenchmarkBTreePut100000(b *testing.B) { b.StopTimer() size := 100000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkPut(b, tree, size) } func BenchmarkBTreeRemove100(b *testing.B) { b.StopTimer() size := 100 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkRemove(b, tree, size) } func BenchmarkBTreeRemove1000(b *testing.B) { b.StopTimer() size := 1000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkRemove(b, tree, size) } func BenchmarkBTreeRemove10000(b *testing.B) { b.StopTimer() size := 10000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkRemove(b, tree, size) } func BenchmarkBTreeRemove100000(b *testing.B) { b.StopTimer() size := 100000 tree := NewWithIntComparator(128) for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } b.StartTimer() benchmarkRemove(b, tree, size) } gods-1.12.0/trees/btree/iterator.go000066400000000000000000000141071335155073000171370ustar00rootroot00000000000000// 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() } gods-1.12.0/trees/btree/serialization.go000066400000000000000000000017551335155073000201700ustar00rootroot00000000000000// 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 the tree. 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 the tree 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 } gods-1.12.0/trees/redblacktree/000077500000000000000000000000001335155073000163025ustar00rootroot00000000000000gods-1.12.0/trees/redblacktree/iterator.go000066400000000000000000000101751335155073000204660ustar00rootroot00000000000000// 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() } gods-1.12.0/trees/redblacktree/redblacktree.go000066400000000000000000000277421335155073000212740ustar00rootroot00000000000000// 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{}) { var insertedNode *Node if tree.Root == nil { // Assert key is of comparator's type for initial tree tree.Comparator(key, key) tree.Root = &Node{Key: key, Value: value, color: red} insertedNode = tree.Root } 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 = &Node{Key: key, Value: value, color: red} insertedNode = node.Left loop = false } else { node = node.Left } case compare > 0: if node.Right == nil { node.Right = &Node{Key: key, Value: value, color: red} insertedNode = node.Right 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 floor 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 are 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 are 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 } gods-1.12.0/trees/redblacktree/redblacktree_test.go000066400000000000000000000443371335155073000223320ustar00rootroot00000000000000// 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, "") } if node, found := tree.Ceiling(0); node != nil || found { t.Errorf("Got %v expected %v", node, "") } 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, "") } 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, "") } } 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) } gods-1.12.0/trees/redblacktree/serialization.go000066400000000000000000000017641335155073000215160ustar00rootroot00000000000000// 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 the tree. 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 the tree 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 } gods-1.12.0/trees/trees.go000066400000000000000000000014051335155073000153240ustar00rootroot00000000000000// 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 trees provides an abstract Tree interface. // // In computer science, a tree is a widely used abstract data type (ADT) or data structure implementing this ADT that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node, represented as a set of linked nodes. // // Reference: https://en.wikipedia.org/wiki/Tree_%28data_structure%29 package trees import "github.com/emirpasic/gods/containers" // Tree interface that all trees implement type Tree interface { containers.Container // Empty() bool // Size() int // Clear() // Values() []interface{} } gods-1.12.0/utils/000077500000000000000000000000001335155073000136715ustar00rootroot00000000000000gods-1.12.0/utils/comparator.go000066400000000000000000000114601335155073000163710ustar00rootroot00000000000000// 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 utils import "time" // Comparator will make type assertion (see IntComparator for example), // which will panic if a or b are not of the asserted type. // // Should return a number: // negative , if a < b // zero , if a == b // positive , if a > b type Comparator func(a, b interface{}) int // StringComparator provides a fast comparison on strings func StringComparator(a, b interface{}) int { s1 := a.(string) s2 := b.(string) min := len(s2) if len(s1) < len(s2) { min = len(s1) } diff := 0 for i := 0; i < min && diff == 0; i++ { diff = int(s1[i]) - int(s2[i]) } if diff == 0 { diff = len(s1) - len(s2) } if diff < 0 { return -1 } if diff > 0 { return 1 } return 0 } // IntComparator provides a basic comparison on int func IntComparator(a, b interface{}) int { aAsserted := a.(int) bAsserted := b.(int) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // Int8Comparator provides a basic comparison on int8 func Int8Comparator(a, b interface{}) int { aAsserted := a.(int8) bAsserted := b.(int8) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // Int16Comparator provides a basic comparison on int16 func Int16Comparator(a, b interface{}) int { aAsserted := a.(int16) bAsserted := b.(int16) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // Int32Comparator provides a basic comparison on int32 func Int32Comparator(a, b interface{}) int { aAsserted := a.(int32) bAsserted := b.(int32) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // Int64Comparator provides a basic comparison on int64 func Int64Comparator(a, b interface{}) int { aAsserted := a.(int64) bAsserted := b.(int64) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // UIntComparator provides a basic comparison on uint func UIntComparator(a, b interface{}) int { aAsserted := a.(uint) bAsserted := b.(uint) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // UInt8Comparator provides a basic comparison on uint8 func UInt8Comparator(a, b interface{}) int { aAsserted := a.(uint8) bAsserted := b.(uint8) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // UInt16Comparator provides a basic comparison on uint16 func UInt16Comparator(a, b interface{}) int { aAsserted := a.(uint16) bAsserted := b.(uint16) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // UInt32Comparator provides a basic comparison on uint32 func UInt32Comparator(a, b interface{}) int { aAsserted := a.(uint32) bAsserted := b.(uint32) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // UInt64Comparator provides a basic comparison on uint64 func UInt64Comparator(a, b interface{}) int { aAsserted := a.(uint64) bAsserted := b.(uint64) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // Float32Comparator provides a basic comparison on float32 func Float32Comparator(a, b interface{}) int { aAsserted := a.(float32) bAsserted := b.(float32) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // Float64Comparator provides a basic comparison on float64 func Float64Comparator(a, b interface{}) int { aAsserted := a.(float64) bAsserted := b.(float64) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // ByteComparator provides a basic comparison on byte func ByteComparator(a, b interface{}) int { aAsserted := a.(byte) bAsserted := b.(byte) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // RuneComparator provides a basic comparison on rune func RuneComparator(a, b interface{}) int { aAsserted := a.(rune) bAsserted := b.(rune) switch { case aAsserted > bAsserted: return 1 case aAsserted < bAsserted: return -1 default: return 0 } } // TimeComparator provides a basic comparison on time.Time func TimeComparator(a, b interface{}) int { aAsserted := a.(time.Time) bAsserted := b.(time.Time) switch { case aAsserted.After(bAsserted): return 1 case aAsserted.Before(bAsserted): return -1 default: return 0 } } gods-1.12.0/utils/comparator_test.go000066400000000000000000000040231335155073000174250ustar00rootroot00000000000000// 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 utils import ( "testing" "time" ) func TestIntComparator(t *testing.T) { // i1,i2,expected tests := [][]interface{}{ {1, 1, 0}, {1, 2, -1}, {2, 1, 1}, {11, 22, -1}, {0, 0, 0}, {1, 0, 1}, {0, 1, -1}, } for _, test := range tests { actual := IntComparator(test[0], test[1]) expected := test[2] if actual != expected { t.Errorf("Got %v expected %v", actual, expected) } } } func TestStringComparator(t *testing.T) { // s1,s2,expected tests := [][]interface{}{ {"a", "a", 0}, {"a", "b", -1}, {"b", "a", 1}, {"aa", "aab", -1}, {"", "", 0}, {"a", "", 1}, {"", "a", -1}, {"", "aaaaaaa", -1}, } for _, test := range tests { actual := StringComparator(test[0], test[1]) expected := test[2] if actual != expected { t.Errorf("Got %v expected %v", actual, expected) } } } func TestTimeComparator(t *testing.T) { now := time.Now() // i1,i2,expected tests := [][]interface{}{ {now, now, 0}, {now.Add(24 * 7 * 2 * time.Hour), now, 1}, {now, now.Add(24 * 7 * 2 * time.Hour), -1}, } for _, test := range tests { actual := TimeComparator(test[0], test[1]) expected := test[2] if actual != expected { t.Errorf("Got %v expected %v", actual, expected) } } } func TestCustomComparator(t *testing.T) { type Custom struct { id int name string } byID := func(a, b interface{}) int { c1 := a.(Custom) c2 := b.(Custom) switch { case c1.id > c2.id: return 1 case c1.id < c2.id: return -1 default: return 0 } } // o1,o2,expected tests := [][]interface{}{ {Custom{1, "a"}, Custom{1, "a"}, 0}, {Custom{1, "a"}, Custom{2, "b"}, -1}, {Custom{2, "b"}, Custom{1, "a"}, 1}, {Custom{1, "a"}, Custom{1, "b"}, 0}, } for _, test := range tests { actual := byID(test[0], test[1]) expected := test[2] if actual != expected { t.Errorf("Got %v expected %v", actual, expected) } } } gods-1.12.0/utils/sort.go000066400000000000000000000014031335155073000152050ustar00rootroot00000000000000// 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 utils import "sort" // Sort sorts values (in-place) with respect to the given comparator. // // Uses Go's sort (hybrid of quicksort for large and then insertion sort for smaller slices). func Sort(values []interface{}, comparator Comparator) { sort.Sort(sortable{values, comparator}) } type sortable struct { values []interface{} comparator Comparator } func (s sortable) Len() int { return len(s.values) } func (s sortable) Swap(i, j int) { s.values[i], s.values[j] = s.values[j], s.values[i] } func (s sortable) Less(i, j int) bool { return s.comparator(s.values[i], s.values[j]) < 0 } gods-1.12.0/utils/sort_test.go000066400000000000000000000035031335155073000162470ustar00rootroot00000000000000// 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 utils import ( "math/rand" "testing" ) func TestSortInts(t *testing.T) { ints := []interface{}{} ints = append(ints, 4) ints = append(ints, 1) ints = append(ints, 2) ints = append(ints, 3) Sort(ints, IntComparator) for i := 1; i < len(ints); i++ { if ints[i-1].(int) > ints[i].(int) { t.Errorf("Not sorted!") } } } func TestSortStrings(t *testing.T) { strings := []interface{}{} strings = append(strings, "d") strings = append(strings, "a") strings = append(strings, "b") strings = append(strings, "c") Sort(strings, StringComparator) for i := 1; i < len(strings); i++ { if strings[i-1].(string) > strings[i].(string) { t.Errorf("Not sorted!") } } } func TestSortStructs(t *testing.T) { type User struct { id int name string } byID := func(a, b interface{}) int { c1 := a.(User) c2 := b.(User) switch { case c1.id > c2.id: return 1 case c1.id < c2.id: return -1 default: return 0 } } // o1,o2,expected users := []interface{}{ User{4, "d"}, User{1, "a"}, User{3, "c"}, User{2, "b"}, } Sort(users, byID) for i := 1; i < len(users); i++ { if users[i-1].(User).id > users[i].(User).id { t.Errorf("Not sorted!") } } } func TestSortRandom(t *testing.T) { ints := []interface{}{} for i := 0; i < 10000; i++ { ints = append(ints, rand.Int()) } Sort(ints, IntComparator) for i := 1; i < len(ints); i++ { if ints[i-1].(int) > ints[i].(int) { t.Errorf("Not sorted!") } } } func BenchmarkGoSortRandom(b *testing.B) { b.StopTimer() ints := []interface{}{} for i := 0; i < 100000; i++ { ints = append(ints, rand.Int()) } b.StartTimer() Sort(ints, IntComparator) b.StopTimer() } gods-1.12.0/utils/utils.go000066400000000000000000000023711335155073000153630ustar00rootroot00000000000000// 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 utils provides common utility functions. // // Provided functionalities: // - sorting // - comparators package utils import ( "fmt" "strconv" ) // ToString converts a value to string. func ToString(value interface{}) string { switch value.(type) { case string: return value.(string) case int8: return strconv.FormatInt(int64(value.(int8)), 10) case int16: return strconv.FormatInt(int64(value.(int16)), 10) case int32: return strconv.FormatInt(int64(value.(int32)), 10) case int64: return strconv.FormatInt(int64(value.(int64)), 10) case uint8: return strconv.FormatUint(uint64(value.(uint8)), 10) case uint16: return strconv.FormatUint(uint64(value.(uint16)), 10) case uint32: return strconv.FormatUint(uint64(value.(uint32)), 10) case uint64: return strconv.FormatUint(uint64(value.(uint64)), 10) case float32: return strconv.FormatFloat(float64(value.(float32)), 'g', -1, 64) case float64: return strconv.FormatFloat(float64(value.(float64)), 'g', -1, 64) case bool: return strconv.FormatBool(value.(bool)) default: return fmt.Sprintf("%+v", value) } } gods-1.12.0/utils/utils_test.go000066400000000000000000000060741335155073000164260ustar00rootroot00000000000000// 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 utils import ( "strings" "testing" ) func TestToStringInts(t *testing.T) { var value interface{} value = int8(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = int16(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = int32(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = int64(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = rune(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } func TestToStringUInts(t *testing.T) { var value interface{} value = uint8(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = uint16(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = uint32(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = uint64(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = byte(1) if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } func TestToStringFloats(t *testing.T) { var value interface{} value = float32(1.123456) if actualValue, expectedValue := ToString(value), "1.123456"; !strings.HasPrefix(actualValue, expectedValue) { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = float32(1.123456) if actualValue, expectedValue := ToString(value), "1.123456"; !strings.HasPrefix(actualValue, expectedValue) { t.Errorf("Got %v expected %v", actualValue, expectedValue) } } func TestToStringOther(t *testing.T) { var value interface{} value = "abc" if actualValue, expectedValue := ToString(value), "abc"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } value = true if actualValue, expectedValue := ToString(value), "true"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } type T struct { id int name string } if actualValue, expectedValue := ToString(T{1, "abc"}), "{id:1 name:abc}"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } }