[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\njobs:\n  test:\n    parameters:\n      version:\n        type: string\n        default: \"1.21\"\n    docker:\n      - image: cimg/go:<<parameters.version>>\n    environment:\n      TEST_RESULTS: /tmp/test-results\n    working_directory: ~/gods\n    steps:\n      - run:\n          name: Print Go version (go version)\n          command: |\n            go version\n      - checkout\n      - run:\n          name: Run tests\n          command: |\n            mkdir -p $TEST_RESULTS\n            go install gotest.tools/gotestsum@latest\n            go test -v ./... | go tool test2json > $TEST_RESULTS/test2json-output.json\n            gotestsum --junitfile $TEST_RESULTS/gotestsum-report.xml\n      - run:\n          name: Calculate test coverage\n          command: |\n            mkdir -p $TEST_RESULTS\n            go test -coverprofile=coverage.out ./... > /dev/null\n            go test -race -coverprofile=coverage.txt -covermode=atomic ./... > /dev/null\n            go tool cover -html=coverage.out -o coverage.html\n            mv coverage.html $TEST_RESULTS\n      - run:\n          name: Upload test coverage\n          command: |\n            bash <(curl -s https://codecov.io/bash)\n      - run:\n          name: Lint (golint)\n          command: |\n            go install golang.org/x/lint/golint@latest\n            golint -set_exit_status ./...\n      - run:\n          name: Enforce formatted code (go fmt)\n          command: |\n            ! go fmt ./... 2>&1 | read\n      - run:\n          name: Examine and report suspicious constructs (go vet)\n          command: |\n            go vet -v ./...\n      - run:\n          name: Calculate cyclomatic complexity (gocyclo)\n          command: |\n            go install github.com/fzipp/gocyclo/cmd/gocyclo@latest\n            gocyclo -avg -over 15 ../gods\n      - run:\n          name: Check for unchecked errors (errcheck)\n          command: |\n            go install github.com/kisielk/errcheck@latest\n            errcheck ./...\n      - store_artifacts:\n          path: /tmp/test-results\n          destination: raw-test-output\n      - store_test_results:\n          path: /tmp/test-results\n\nworkflows:\n  test:\n    jobs:\n      - test:\n          matrix:\n            parameters:\n              # To test with and without generics (versions prior to 1.18)\n              version: [ \"1.21\" ]\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# Ref: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL\"\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [ master ]\n  schedule:\n    - cron: '30 4 * * 5'\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'go' ]\n        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]\n        # Learn more about CodeQL language support at https://git.io/codeql-language-support\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v3\n\n    # Initializes the CodeQL tools for scanning.\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v2\n      with:\n        languages: ${{ matrix.language }}\n        # If you wish to specify custom queries, you can do so here or in a config file.\n        # By default, queries listed here will override any specified in a config file.\n        # Prefix the list here with \"+\" to use these queries and those in the config file.\n        # queries: ./path/to/local/query, your-org/your-repo/queries@main\n\n    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).\n    # If this step fails, then you should remove it and run the build manually (see below)\n    - name: Autobuild\n      uses: github/codeql-action/autobuild@v2\n\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 https://git.io/JvXDl\n\n    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines\n    #    and modify them (or add more) to build your code if your project\n    #    uses a compiled language\n\n    #- run: |\n    #   make bootstrap\n    #   make release\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v2\n"
  },
  {
    "path": ".gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n\n.idea"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2015, Emir Pasic\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-------------------------------------------------------------------------------\n\nAVL Tree:\n\nCopyright (c) 2017 Benjamin Scher Purcell <benjapurcell@gmail.com>\n\nPermission to use, copy, modify, and distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![GoDoc](https://godoc.org/github.com/emirpasic/gods?status.svg)](https://godoc.org/github.com/emirpasic/gods)\n[![Build Status](https://circleci.com/gh/emirpasic/gods/tree/master.svg?style=shield)](https://circleci.com/gh/emirpasic/gods?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/emirpasic/gods)](https://goreportcard.com/report/github.com/emirpasic/gods)\n[![codecov](https://codecov.io/gh/emirpasic/gods/branch/master/graph/badge.svg)](https://codecov.io/gh/emirpasic/gods)\n[![Sourcegraph](https://sourcegraph.com/github.com/emirpasic/gods/-/badge.svg)](https://sourcegraph.com/github.com/emirpasic/gods?badge)\n[![Release](https://img.shields.io/github/release/emirpasic/gods.svg?style=flat-square)](https://github.com/emirpasic/gods/releases)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=gods&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=gods)\n[![PyPI](https://img.shields.io/badge/License-BSD_2--Clause-green.svg)](https://github.com/emirpasic/gods/blob/master/LICENSE)\n\n# GoDS (Go Data Structures)\n\nImplementation of various data structures and algorithms in Go.\n\n## Data Structures\n\n- [Containers](#containers)\n  - [Lists](#lists)\n    - [ArrayList](#arraylist)\n    - [SinglyLinkedList](#singlylinkedlist)\n    - [DoublyLinkedList](#doublylinkedlist)\n  - [Sets](#sets)\n    - [HashSet](#hashset)\n    - [TreeSet](#treeset)\n    - [LinkedHashSet](#linkedhashset)\n  - [Stacks](#stacks)\n    - [LinkedListStack](#linkedliststack)\n    - [ArrayStack](#arraystack)\n  - [Maps](#maps)\n    - [HashMap](#hashmap)\n    - [TreeMap](#treemap)\n    - [LinkedHashMap](#linkedhashmap)\n    - [HashBidiMap](#hashbidimap)\n    - [TreeBidiMap](#treebidimap)\n  - [Trees](#trees)\n    - [RedBlackTree](#redblacktree)\n    - [AVLTree](#avltree)\n    - [BTree](#btree)\n    - [BinaryHeap](#binaryheap)\n  - [Queues](#queues)\n    - [LinkedListQueue](#linkedlistqueue)\n    - [ArrayQueue](#arrayqueue)\n    - [CircularBuffer](#circularbuffer)\n    - [PriorityQueue](#priorityqueue)\n- [Functions](#functions)\n    - [Comparator](#comparator)\n    - [Iterator](#iterator)\n      - [IteratorWithIndex](#iteratorwithindex)\n      - [IteratorWithKey](#iteratorwithkey)\n      - [ReverseIteratorWithIndex](#reverseiteratorwithindex)\n      - [ReverseIteratorWithKey](#reverseiteratorwithkey)\n    - [Enumerable](#enumerable)\n      - [EnumerableWithIndex](#enumerablewithindex)\n      - [EnumerableWithKey](#enumerablewithkey)\n    - [Serialization](#serialization)\n      - [JSONSerializer](#jsonserializer)\n      - [JSONDeserializer](#jsondeserializer)\n    - [Sort](#sort)\n    - [Container](#container)\n- [Appendix](#appendix)\n\n\n## Containers\n\nAll data structures implement the container interface with the following methods:\n\n```go\ntype Container interface {\n\tEmpty() bool\n\tSize() int\n\tClear()\n\tValues() []interface{}\n\tString() string\n}\n```\n\nContainers are either ordered or unordered. All ordered containers provide [stateful iterators](#iterator) and some of them allow [enumerable functions](#enumerable).\n\n| **Data** | **Structure**                         | **Ordered** | **[Iterator](#iterator)** | **[Enumerable](#enumerable)** | **Referenced by** |\n| :--- |:--------------------------------------| :---: | :---: | :---: | :---: |\n| [Lists](#lists) |\n|   | [ArrayList](#arraylist)               | yes | yes* | yes | index |\n|   | [SinglyLinkedList](#singlylinkedlist) | yes | yes | yes | index |\n|   | [DoublyLinkedList](#doublylinkedlist) | yes | yes* | yes | index |\n| [Sets](#sets) |\n|   | [HashSet](#hashset)                   | no | no | no | index |\n|   | [TreeSet](#treeset)                   | yes | yes* | yes | index |\n|   | [LinkedHashSet](#linkedhashset)       | yes | yes* | yes | index |\n| [Stacks](#stacks) |\n|   | [LinkedListStack](#linkedliststack)   | yes | yes | no | index |\n|   | [ArrayStack](#arraystack)             | yes | yes* | no | index |\n| [Maps](#maps) |\n|   | [HashMap](#hashmap)                   | no | no | no | key |\n|   | [TreeMap](#treemap)                   | yes | yes* | yes | key |\n|   | [LinkedHashMap](#linkedhashmap)       | yes | yes* | yes | key |\n|   | [HashBidiMap](#hashbidimap)           | no | no | no | key* |\n|   | [TreeBidiMap](#treebidimap)           | yes | yes* | yes | key* |\n| [Trees](#trees) |\n|   | [RedBlackTree](#redblacktree)         | yes | yes* | no | key |\n|   | [AVLTree](#avltree)                   | yes | yes* | no | key |\n|   | [BTree](#btree)                       | yes | yes* | no | key |\n|   | [BinaryHeap](#binaryheap)             | yes | yes* | no | index |\n| [Queues](#queues) |\n|   | [LinkedListQueue](#linkedlistqueue)   | yes | yes | no | index |\n|   | [ArrayQueue](#arrayqueue)             | yes | yes* | no | index |\n|   | [CircularBuffer](#circularbuffer)     | yes | yes* | no | index |\n|   | [PriorityQueue](#priorityqueue)       | yes | yes* | no | index |\n|   |                                       |  | <sub><sup>*reversible</sup></sub> |  | <sub><sup>*bidirectional</sup></sub> |\n\n### Lists\n\nA list is a data structure that stores values and may have repeated values.\n\nImplements [Container](#containers) interface.\n\n```go\ntype List interface {\n\tGet(index int) (interface{}, bool)\n\tRemove(index int)\n\tAdd(values ...interface{})\n\tContains(values ...interface{}) bool\n\tSort(comparator utils.Comparator)\n\tSwap(index1, index2 int)\n\tInsert(index int, values ...interface{})\n\tSet(index int, value interface{})\n\n\tcontainers.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n    // String() string\n}\n```\n\n#### ArrayList\n\nA [list](#lists) backed by a dynamic array that grows and shrinks implicitly.\n\nImplements [List](#lists), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport (\n\t\"github.com/emirpasic/gods/lists/arraylist\"\n\t\"github.com/emirpasic/gods/utils\"\n)\n\nfunc main() {\n\tlist := arraylist.New()\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Add(\"c\", \"b\")                    // [\"a\",\"c\",\"b\"]\n\tlist.Sort(utils.StringComparator)     // [\"a\",\"b\",\"c\"]\n\t_, _ = list.Get(0)                    // \"a\",true\n\t_, _ = list.Get(100)                  // nil,false\n\t_ = list.Contains(\"a\", \"b\", \"c\")      // true\n\t_ = list.Contains(\"a\", \"b\", \"c\", \"d\") // false\n\tlist.Swap(0, 1)                       // [\"b\",\"a\",c\"]\n\tlist.Remove(2)                        // [\"b\",\"a\"]\n\tlist.Remove(1)                        // [\"b\"]\n\tlist.Remove(0)                        // []\n\tlist.Remove(0)                        // [] (ignored)\n\t_ = list.Empty()                      // true\n\t_ = list.Size()                       // 0\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Clear()                          // []\n\tlist.Insert(0, \"b\")                   // [\"b\"]\n\tlist.Insert(0, \"a\")                   // [\"a\",\"b\"]\n}\n```\n\n#### SinglyLinkedList\n\nA [list](#lists) where each element points to the next element in the list.\n\nImplements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport (\n\tsll \"github.com/emirpasic/gods/lists/singlylinkedlist\"\n\t\"github.com/emirpasic/gods/utils\"\n)\n\nfunc main() {\n\tlist := sll.New()\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Add(\"c\", \"b\")                    // [\"a\",\"c\",\"b\"]\n\tlist.Sort(utils.StringComparator)     // [\"a\",\"b\",\"c\"]\n\t_, _ = list.Get(0)                    // \"a\",true\n\t_, _ = list.Get(100)                  // nil,false\n\t_ = list.Contains(\"a\", \"b\", \"c\")      // true\n\t_ = list.Contains(\"a\", \"b\", \"c\", \"d\") // false\n\tlist.Swap(0, 1)                       // [\"b\",\"a\",c\"]\n\tlist.Remove(2)                        // [\"b\",\"a\"]\n\tlist.Remove(1)                        // [\"b\"]\n\tlist.Remove(0)                        // []\n\tlist.Remove(0)                        // [] (ignored)\n\t_ = list.Empty()                      // true\n\t_ = list.Size()                       // 0\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Clear()                          // []\n\tlist.Insert(0, \"b\")                   // [\"b\"]\n\tlist.Insert(0, \"a\")                   // [\"a\",\"b\"]\n}\n```\n\n#### DoublyLinkedList\n\nA [list](#lists) where each element points to the next and previous elements in the list.\n\nImplements [List](#lists), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport (\n\tdll \"github.com/emirpasic/gods/lists/doublylinkedlist\"\n\t\"github.com/emirpasic/gods/utils\"\n)\n\nfunc main() {\n\tlist := dll.New()\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Add(\"c\", \"b\")                    // [\"a\",\"c\",\"b\"]\n\tlist.Sort(utils.StringComparator)     // [\"a\",\"b\",\"c\"]\n\t_, _ = list.Get(0)                    // \"a\",true\n\t_, _ = list.Get(100)                  // nil,false\n\t_ = list.Contains(\"a\", \"b\", \"c\")      // true\n\t_ = list.Contains(\"a\", \"b\", \"c\", \"d\") // false\n\tlist.Swap(0, 1)                       // [\"b\",\"a\",c\"]\n\tlist.Remove(2)                        // [\"b\",\"a\"]\n\tlist.Remove(1)                        // [\"b\"]\n\tlist.Remove(0)                        // []\n\tlist.Remove(0)                        // [] (ignored)\n\t_ = list.Empty()                      // true\n\t_ = list.Size()                       // 0\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Clear()                          // []\n\tlist.Insert(0, \"b\")                   // [\"b\"]\n\tlist.Insert(0, \"a\")                   // [\"a\",\"b\"]\n}\n```\n\n### Sets\n\nA 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.\n\nSet additionally allow set operations such as [intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)), [union](https://en.wikipedia.org/wiki/Union_(set_theory)), [difference](https://proofwiki.org/wiki/Definition:Set_Difference), etc.\n\nImplements [Container](#containers) interface.\n\n```go\ntype Set interface {\n\tAdd(elements ...interface{})\n\tRemove(elements ...interface{})\n\tContains(elements ...interface{}) bool\n    // Intersection(another *Set) *Set\n    // Union(another *Set) *Set\n    // Difference(another *Set) *Set\n\t\n\tcontainers.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n```\n\n#### HashSet\n\nA [set](#sets) backed by a hash table (actually a Go's map). It makes no guarantees as to the iteration order of the set.\n\nImplements [Set](#sets), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/sets/hashset\"\n\nfunc main() {\n\tset := hashset.New()   // empty\n\tset.Add(1)             // 1\n\tset.Add(2, 2, 3, 4, 5) // 3, 1, 2, 4, 5 (random order, duplicates ignored)\n\tset.Remove(4)          // 5, 3, 2, 1 (random order)\n\tset.Remove(2, 3)       // 1, 5 (random order)\n\tset.Contains(1)        // true\n\tset.Contains(1, 5)     // true\n\tset.Contains(1, 6)     // false\n\t_ = set.Values()       // []int{5,1} (random order)\n\tset.Clear()            // empty\n\tset.Empty()            // true\n\tset.Size()             // 0\n}\n```\n\n#### TreeSet\n\nA [set](#sets) backed by a [red-black tree](#redblacktree) to keep the elements ordered with respect to the [comparator](#comparator).\n\nImplements [Set](#sets), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/sets/treeset\"\n\nfunc main() {\n\tset := treeset.NewWithIntComparator() // empty (keys are of type int)\n\tset.Add(1)                            // 1\n\tset.Add(2, 2, 3, 4, 5)                // 1, 2, 3, 4, 5 (in order, duplicates ignored)\n\tset.Remove(4)                         // 1, 2, 3, 5 (in order)\n\tset.Remove(2, 3)                      // 1, 5 (in order)\n\tset.Contains(1)                       // true\n\tset.Contains(1, 5)                    // true\n\tset.Contains(1, 6)                    // false\n\t_ = set.Values()                      // []int{1,5} (in order)\n\tset.Clear()                           // empty\n\tset.Empty()                           // true\n\tset.Size()                            // 0\n}\n```\n\n#### LinkedHashSet\n\nA [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.\n\nImplements [Set](#sets), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/sets/linkedhashset\"\n\nfunc main() {\n\tset := linkedhashset.New() // empty\n\tset.Add(5)                 // 5\n\tset.Add(4, 4, 3, 2, 1)     // 5, 4, 3, 2, 1 (in insertion-order, duplicates ignored)\n\tset.Add(4)                 // 5, 4, 3, 2, 1 (duplicates ignored, insertion-order unchanged)\n\tset.Remove(4)              // 5, 3, 2, 1 (in insertion-order)\n\tset.Remove(2, 3)           // 5, 1 (in insertion-order)\n\tset.Contains(1)            // true\n\tset.Contains(1, 5)         // true\n\tset.Contains(1, 6)         // false\n\t_ = set.Values()           // []int{5, 1} (in insertion-order)\n\tset.Clear()                // empty\n\tset.Empty()                // true\n\tset.Size()                 // 0\n}\n```\n\n### Stacks\n\nA 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.\n\nImplements [Container](#containers) interface.\n\n```go\ntype Stack interface {\n\tPush(value interface{})\n\tPop() (value interface{}, ok bool)\n\tPeek() (value interface{}, ok bool)\n\n\tcontainers.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n```\n\n#### LinkedListStack\n\nA [stack](#stacks) based on a [linked list](#singlylinkedlist).\n\nImplements [Stack](#stacks), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport lls \"github.com/emirpasic/gods/stacks/linkedliststack\"\n\nfunc main() {\n\tstack := lls.New()  // empty\n\tstack.Push(1)       // 1\n\tstack.Push(2)       // 1, 2\n\tstack.Values()      // 2, 1 (LIFO order)\n\t_, _ = stack.Peek() // 2,true\n\t_, _ = stack.Pop()  // 2, true\n\t_, _ = stack.Pop()  // 1, true\n\t_, _ = stack.Pop()  // nil, false (nothing to pop)\n\tstack.Push(1)       // 1\n\tstack.Clear()       // empty\n\tstack.Empty()       // true\n\tstack.Size()        // 0\n}\n```\n\n#### ArrayStack\n\nA [stack](#stacks) based on a [array list](#arraylist).\n\nImplements [Stack](#stacks), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/stacks/arraystack\"\n\nfunc main() {\n\tstack := arraystack.New() // empty\n\tstack.Push(1)             // 1\n\tstack.Push(2)             // 1, 2\n\tstack.Values()            // 2, 1 (LIFO order)\n\t_, _ = stack.Peek()       // 2,true\n\t_, _ = stack.Pop()        // 2, true\n\t_, _ = stack.Pop()        // 1, true\n\t_, _ = stack.Pop()        // nil, false (nothing to pop)\n\tstack.Push(1)             // 1\n\tstack.Clear()             // empty\n\tstack.Empty()             // true\n\tstack.Size()              // 0\n}\n```\n\n### Maps\n\nA 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.\n\nImplements [Container](#containers) interface.\n\n```go\ntype Map interface {\n\tPut(key interface{}, value interface{})\n\tGet(key interface{}) (value interface{}, found bool)\n\tRemove(key interface{})\n\tKeys() []interface{}\n\n\tcontainers.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n```\n\nA 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.\n\n```go\ntype BidiMap interface {\n\tGetKey(value interface{}) (key interface{}, found bool)\n\n\tMap\n}\n```\n\n#### HashMap\n\nA [map](#maps) based on hash tables. Keys are unordered.\n\nImplements [Map](#maps), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/maps/hashmap\"\n\nfunc main() {\n\tm := hashmap.New() // empty\n\tm.Put(1, \"x\")      // 1->x\n\tm.Put(2, \"b\")      // 2->b, 1->x (random order)\n\tm.Put(1, \"a\")      // 2->b, 1->a (random order)\n\t_, _ = m.Get(2)    // b, true\n\t_, _ = m.Get(3)    // nil, false\n\t_ = m.Values()     // []interface {}{\"b\", \"a\"} (random order)\n\t_ = m.Keys()       // []interface {}{1, 2} (random order)\n\tm.Remove(1)        // 2->b\n\tm.Clear()          // empty\n\tm.Empty()          // true\n\tm.Size()           // 0\n}\n```\n\n#### TreeMap\n\nA [map](#maps) based on [red-black tree](#redblacktree). Keys are ordered with respect to the [comparator](#comparator).\n\nImplements [Map](#maps), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/maps/treemap\"\n\nfunc main() {\n\tm := treemap.NewWithIntComparator() // empty (keys are of type int)\n\tm.Put(1, \"x\")                       // 1->x\n\tm.Put(2, \"b\")                       // 1->x, 2->b (in order)\n\tm.Put(1, \"a\")                       // 1->a, 2->b (in order)\n\t_, _ = m.Get(2)                     // b, true\n\t_, _ = m.Get(3)                     // nil, false\n\t_ = m.Values()                      // []interface {}{\"a\", \"b\"} (in order)\n\t_ = m.Keys()                        // []interface {}{1, 2} (in order)\n\tm.Remove(1)                         // 2->b\n\tm.Clear()                           // empty\n\tm.Empty()                           // true\n\tm.Size()                            // 0\n\n\t// Other:\n\tm.Min() // Returns the minimum key and its value from map.\n\tm.Max() // Returns the maximum key and its value from map.\n}\n```\n\n#### LinkedHashMap\n\nA [map](#maps) that preserves insertion-order. It is backed by a hash table to store values and [doubly-linked list](doublylinkedlist) to store ordering.\n\nImplements [Map](#maps), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/maps/linkedhashmap\"\n\nfunc main() {\n\tm := linkedhashmap.New() // empty (keys are of type int)\n\tm.Put(2, \"b\")            // 2->b\n\tm.Put(1, \"x\")            // 2->b, 1->x (insertion-order)\n\tm.Put(1, \"a\")            // 2->b, 1->a (insertion-order)\n\t_, _ = m.Get(2)          // b, true\n\t_, _ = m.Get(3)          // nil, false\n\t_ = m.Values()           // []interface {}{\"b\", \"a\"} (insertion-order)\n\t_ = m.Keys()             // []interface {}{2, 1} (insertion-order)\n\tm.Remove(1)              // 2->b\n\tm.Clear()                // empty\n\tm.Empty()                // true\n\tm.Size()                 // 0\n}\n\n```\n\n#### HashBidiMap\n\nA [map](#maps) based on two hashmaps. Keys are unordered.\n\nImplements [BidiMap](#maps), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/maps/hashbidimap\"\n\nfunc main() {\n\tm := hashbidimap.New() // empty\n\tm.Put(1, \"x\")          // 1->x\n\tm.Put(3, \"b\")          // 1->x, 3->b (random order)\n\tm.Put(1, \"a\")          // 1->a, 3->b (random order)\n\tm.Put(2, \"b\")          // 1->a, 2->b (random order)\n\t_, _ = m.GetKey(\"a\")   // 1, true\n\t_, _ = m.Get(2)        // b, true\n\t_, _ = m.Get(3)        // nil, false\n\t_ = m.Values()         // []interface {}{\"a\", \"b\"} (random order)\n\t_ = m.Keys()           // []interface {}{1, 2} (random order)\n\tm.Remove(1)            // 2->b\n\tm.Clear()              // empty\n\tm.Empty()              // true\n\tm.Size()               // 0\n}\n```\n\n#### TreeBidiMap\n\nA [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.\n\nImplements [BidiMap](#maps), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport (\n\t\"github.com/emirpasic/gods/maps/treebidimap\"\n\t\"github.com/emirpasic/gods/utils\"\n)\n\nfunc main() {\n\tm := treebidimap.NewWith(utils.IntComparator, utils.StringComparator)\n\tm.Put(1, \"x\")        // 1->x\n\tm.Put(3, \"b\")        // 1->x, 3->b (ordered)\n\tm.Put(1, \"a\")        // 1->a, 3->b (ordered)\n\tm.Put(2, \"b\")        // 1->a, 2->b (ordered)\n\t_, _ = m.GetKey(\"a\") // 1, true\n\t_, _ = m.Get(2)      // b, true\n\t_, _ = m.Get(3)      // nil, false\n\t_ = m.Values()       // []interface {}{\"a\", \"b\"} (ordered)\n\t_ = m.Keys()         // []interface {}{1, 2} (ordered)\n\tm.Remove(1)          // 2->b\n\tm.Clear()            // empty\n\tm.Empty()            // true\n\tm.Size()             // 0\n}\n```\n\n### Trees\n\nA 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.\n\nImplements [Container](#containers) interface.\n\n```go\ntype Tree interface {\n\tcontainers.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n```\n\n#### RedBlackTree\n\nA 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.\n\nThe 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. <sub><sup>[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree)</sup></sub>\n\nImplements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n<p align=\"center\"><img src=\"http://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Red-black_tree_example.svg/500px-Red-black_tree_example.svg.png\" width=\"400px\" height=\"200px\" /></p>\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\trbt \"github.com/emirpasic/gods/trees/redblacktree\"\n)\n\nfunc main() {\n\ttree := rbt.NewWithIntComparator() // empty (keys are of type int)\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\n\tfmt.Println(tree)\n\t//\n\t//  RedBlackTree\n\t//  │           ┌── 6\n\t//\t│       ┌── 5\n\t//\t│   ┌── 4\n\t//\t│   │   └── 3\n\t//\t└── 2\n\t//\t\t└── 1\n\n\t_ = tree.Values() // []interface {}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"} (in order)\n\t_ = tree.Keys()   // []interface {}{1, 2, 3, 4, 5, 6} (in order)\n\n\ttree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)\n\tfmt.Println(tree)\n\t//\n\t//  RedBlackTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      │   ┌── 3\n\t//      └── 1\n\n\ttree.Clear() // empty\n\ttree.Empty() // true\n\ttree.Size()  // 0\n\n\t// Other:\n\ttree.Left() // gets the left-most (min) node\n\ttree.Right() // get the right-most (max) node\n\ttree.Floor(1) // get the floor node\n\ttree.Ceiling(1) // get the ceiling node\n}\n```\n\nExtending the red-black tree's functionality  has been demonstrated in the following [example](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended/redblacktreeextended.go).\n\n#### AVLTree\n\nAVL [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.\n\nAVL 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. <sub><sup>[Wikipedia](https://en.wikipedia.org/wiki/AVL_tree)</sup></sub>\n\nImplements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n<p align=\"center\"><img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/AVL-tree-wBalance_K.svg/262px-AVL-tree-wBalance_K.svg.png\" width=\"300px\" height=\"180px\" /><br/><sub>AVL tree with balance factors (green)</sub></p>\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\tavl \"github.com/emirpasic/gods/trees/avltree\"\n)\n\nfunc main() {\n\ttree := avl.NewWithIntComparator() // empty(keys are of type int)\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\n\tfmt.Println(tree)\n\t//\n\t//  AVLTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      │   ┌── 3\n\t//      └── 2\n\t//          └── 1\n\n\n\t_ = tree.Values() // []interface {}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"} (in order)\n\t_ = tree.Keys()   // []interface {}{1, 2, 3, 4, 5, 6} (in order)\n\n\ttree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)\n\tfmt.Println(tree)\n\t//\n\t//  AVLTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      └── 3\n\t//          └── 1\n\n\ttree.Clear() // empty\n\ttree.Empty() // true\n\ttree.Size()  // 0\n}\n```\n\n#### BTree\n\nB-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.\n\nAccording to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties:\n\n- Every node has at most m children.\n- Every non-leaf node (except root) has at least ⌈m/2⌉ children.\n- The root has at least two children if it is not a leaf node.\n- A non-leaf node with k children contains k−1 keys.\n- All leaves appear in the same level\n\nEach 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.<sub><sup>[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree)</sub></sup>\n\nImplements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n<p align=\"center\"><img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/B-tree.svg/831px-B-tree.svg.png\" width=\"400px\" height=\"111px\" /></p>\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/trees/btree\"\n)\n\nfunc main() {\n\ttree := btree.NewWithIntComparator(3) // empty (keys are of type int)\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\ttree.Put(7, \"g\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order)\n\n\tfmt.Println(tree)\n\t// BTree\n\t//         1\n\t//     2\n\t//         3\n\t// 4\n\t//         5\n\t//     6\n\t//         7\n\n\t_ = tree.Values() // []interface {}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"} (in order)\n\t_ = tree.Keys()   // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order)\n\n\ttree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f, 7->g (in order)\n\tfmt.Println(tree)\n\t// BTree\n\t//     1\n\t//     3\n\t// 4\n\t//     5\n\t// 6\n\t//     7\n\n\ttree.Clear() // empty\n\ttree.Empty() // true\n\ttree.Size()  // 0\n\n\t// Other:\n\ttree.Height() // gets the height of the tree\n\ttree.Left() // gets the left-most (min) node\n\ttree.LeftKey() // get the left-most (min) node's key\n\ttree.LeftValue() // get the left-most (min) node's value\n\ttree.Right() // get the right-most (max) node\n\ttree.RightKey() // get the right-most (max) node's key\n\ttree.RightValue() // get the right-most (max) node's value\n}\n```\n\n#### BinaryHeap\n\nA binary heap is a [tree](#trees) created using a binary tree. It can be seen as a binary tree with two additional constraints:\n\n- Shape property:\n\n  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.\n- Heap property:\n\n  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. <sub><sup>[Wikipedia](http://en.wikipedia.org/wiki/Binary_heap)</sub></sup>\n\nImplements [Tree](#trees), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n<p align=\"center\"><img src=\"http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Max-Heap.svg/501px-Max-Heap.svg.png\" width=\"300px\" height=\"200px\" /></p>\n\n```go\npackage main\n\nimport (\n\t\"github.com/emirpasic/gods/trees/binaryheap\"\n\t\"github.com/emirpasic/gods/utils\"\n)\n\nfunc main() {\n\n\t// Min-heap\n\theap := binaryheap.NewWithIntComparator() // empty (min-heap)\n\theap.Push(2)                              // 2\n\theap.Push(3)                              // 2, 3\n\theap.Push(1)                              // 1, 3, 2\n\theap.Values()                             // 1, 3, 2\n\t_, _ = heap.Peek()                        // 1,true\n\t_, _ = heap.Pop()                         // 1, true\n\t_, _ = heap.Pop()                         // 2, true\n\t_, _ = heap.Pop()                         // 3, true\n\t_, _ = heap.Pop()                         // nil, false (nothing to pop)\n\theap.Push(1)                              // 1\n\theap.Clear()                              // empty\n\theap.Empty()                              // true\n\theap.Size()                               // 0\n\n\t// Max-heap\n\tinverseIntComparator := func(a, b interface{}) int {\n\t\treturn -utils.IntComparator(a, b)\n\t}\n\theap = binaryheap.NewWith(inverseIntComparator) // empty (min-heap)\n\theap.Push(2, 3, 1)                              // 3, 2, 1 (bulk optimized)\n\theap.Values()                                   // 3, 2, 1\n}\n```\n\n### Queues\n\nA queue that represents a first-in-first-out (FIFO) data structure. The usual enqueue and dequeue operations are provided, as well as a method to peek at the first item in the queue.\n\n<p align=\"center\"><img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Data_Queue.svg/300px-Data_Queue.svg.png\" width=\"200px\" height=\"120px\" /></p>\n\nImplements [Container](#containers) interface.\n\n```go\ntype Queue interface {\n\tEnqueue(value interface{})\n\tDequeue() (value interface{}, ok bool)\n\tPeek() (value interface{}, ok bool)\n\n\tcontainers.Container\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n```\n\n#### LinkedListQueue\n\nA [queue](#queues) based on a [linked list](#singlylinkedlist).\n\nImplements [Queue](#queues), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport llq \"github.com/emirpasic/gods/queues/linkedlistqueue\"\n\n// LinkedListQueueExample to demonstrate basic usage of LinkedListQueue\nfunc main() {\n    queue := llq.New()     // empty\n    queue.Enqueue(1)       // 1\n    queue.Enqueue(2)       // 1, 2\n    _ = queue.Values()     // 1, 2 (FIFO order)\n    _, _ = queue.Peek()    // 1,true\n    _, _ = queue.Dequeue() // 1, true\n    _, _ = queue.Dequeue() // 2, true\n    _, _ = queue.Dequeue() // nil, false (nothing to deque)\n    queue.Enqueue(1)       // 1\n    queue.Clear()          // empty\n    queue.Empty()          // true\n    _ = queue.Size()       // 0\n}\n```\n\n#### ArrayQueue\n\nA [queue](#queues) based on a [array list](#arraylist).\n\nImplements [Queue](#queues), [ReverseIteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport aq \"github.com/emirpasic/gods/queues/arrayqueue\"\n\n// ArrayQueueExample to demonstrate basic usage of ArrayQueue\nfunc main() {\n    queue := aq.New()      // empty\n    queue.Enqueue(1)       // 1\n    queue.Enqueue(2)       // 1, 2\n    _ = queue.Values()     // 1, 2 (FIFO order)\n    _, _ = queue.Peek()    // 1,true\n    _, _ = queue.Dequeue() // 1, true\n    _, _ = queue.Dequeue() // 2, true\n    _, _ = queue.Dequeue() // nil, false (nothing to deque)\n    queue.Enqueue(1)       // 1\n    queue.Clear()          // empty\n    queue.Empty()          // true\n    _ = queue.Size()       // 0\n}\n```\n\n#### CircularBuffer\n\nA circular buffer, circular [queue](#queues), cyclic buffer or ring buffer is a data structure that uses a single, fixed-size buffer as if it were connected end-to-end. This structure lends itself easily to buffering data streams.\n\n<p align=\"center\"><img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Circular_Buffer_Animation.gif/400px-Circular_Buffer_Animation.gif\" width=\"300px\" height=\"300px\" /></p>\n\nImplements [Queue](#queues), [ReverseIteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport cb \"github.com/emirpasic/gods/queues/circularbuffer\"\n\n// CircularBufferExample to demonstrate basic usage of CircularBuffer\nfunc main() {\n    queue := cb.New(3)     // empty (max size is 3)\n    queue.Enqueue(1)       // 1\n    queue.Enqueue(2)       // 1, 2\n    queue.Enqueue(3)       // 1, 2, 3\n    _ = queue.Values()     // 1, 2, 3\n    queue.Enqueue(3)       // 4, 2, 3\n    _, _ = queue.Peek()    // 4,true\n    _, _ = queue.Dequeue() // 4, true\n    _, _ = queue.Dequeue() // 2, true\n    _, _ = queue.Dequeue() // 3, true\n    _, _ = queue.Dequeue() // nil, false (nothing to deque)\n    queue.Enqueue(1)       // 1\n    queue.Clear()          // empty\n    queue.Empty()          // true\n    _ = queue.Size()       // 0\n}\n```\n\n#### PriorityQueue\n\nA priority queue is a special type of [queue](#queues) in which each element is associated with a priority value. And, elements are served on the basis of their priority. That is, higher priority elements are served first. However, if elements with the same priority occur, they are served according to their order in the queue.\n\nImplements [Queue](#queues), [ReverseIteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces.\n\n```go\npackage main\n\nimport (\n  pq \"github.com/emirpasic/gods/queues/priorityqueue\"\n  \"github.com/emirpasic/gods/utils\"\n)\n\n// Element is an entry in the priority queue\ntype Element struct {\n    name     string\n    priority int\n}\n\n// Comparator function (sort by element's priority value in descending order)\nfunc byPriority(a, b interface{}) int {\n    priorityA := a.(Element).priority\n    priorityB := b.(Element).priority\n    return -utils.IntComparator(priorityA, priorityB) // \"-\" descending order\n}\n\n// PriorityQueueExample to demonstrate basic usage of BinaryHeap\nfunc main() {\n    a := Element{name: \"a\", priority: 1}\n    b := Element{name: \"b\", priority: 2}\n    c := Element{name: \"c\", priority: 3}\n    \n    queue := pq.NewWith(byPriority) // empty\n    queue.Enqueue(a)                // {a 1}\n    queue.Enqueue(c)                // {c 3}, {a 1}\n    queue.Enqueue(b)                // {c 3}, {b 2}, {a 1}\n    _ = queue.Values()              // [{c 3} {b 2} {a 1}]\n    _, _ = queue.Peek()             // {c 3} true\n    _, _ = queue.Dequeue()          // {c 3} true\n    _, _ = queue.Dequeue()          // {b 2} true\n    _, _ = queue.Dequeue()          // {a 1} true\n    _, _ = queue.Dequeue()          // <nil> false (nothing to dequeue)\n    queue.Clear()                   // empty\n    _ = queue.Empty()               // true\n    _ = queue.Size()                // 0\n}\n```\n\n## Functions\n\nVarious helper functions used throughout the library.\n\n### Comparator\n\nSome 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.\n\nComparator is defined as:\n\nReturn values (int):\n\n```go\nnegative , if a < b\nzero     , if a == b\npositive , if a > b\n```\n\nComparator signature:\n\n```go\ntype Comparator func(a, b interface{}) int\n```\n\nAll common comparators for builtin types are included in the library:\n\n```go\nfunc StringComparator(a, b interface{}) int\n\nfunc IntComparator(a, b interface{}) int\n\nfunc Int8Comparator(a, b interface{}) int\n\nfunc Int16Comparator(a, b interface{}) int\n\nfunc Int32Comparator(a, b interface{}) int\n\nfunc Int64Comparator(a, b interface{}) int\n\nfunc UIntComparator(a, b interface{}) int\n\nfunc UInt8Comparator(a, b interface{}) int\n\nfunc UInt16Comparator(a, b interface{}) int\n\nfunc UInt32Comparator(a, b interface{}) int\n\nfunc UInt64Comparator(a, b interface{}) int\n\nfunc Float32Comparator(a, b interface{}) int\n\nfunc Float64Comparator(a, b interface{}) int\n\nfunc ByteComparator(a, b interface{}) int\n\nfunc RuneComparator(a, b interface{}) int\n\nfunc TimeComparator(a, b interface{}) int\n```\n\nWriting custom comparators is easy:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/sets/treeset\"\n)\n\ntype User struct {\n\tid   int\n\tname string\n}\n\n// Custom comparator (sort by IDs)\nfunc byID(a, b interface{}) int {\n\n\t// Type assertion, program will panic if this is not respected\n\tc1 := a.(User)\n\tc2 := b.(User)\n\n\tswitch {\n\tcase c1.id > c2.id:\n\t\treturn 1\n\tcase c1.id < c2.id:\n\t\treturn -1\n\tdefault:\n\t\treturn 0\n\t}\n}\n\nfunc main() {\n\tset := treeset.NewWith(byID)\n\n\tset.Add(User{2, \"Second\"})\n\tset.Add(User{3, \"Third\"})\n\tset.Add(User{1, \"First\"})\n\tset.Add(User{4, \"Fourth\"})\n\n\tfmt.Println(set) // {1 First}, {2 Second}, {3 Third}, {4 Fourth}\n}\n```\n\n### Iterator\n\nAll 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.\n\nNote: it is unsafe to remove elements from container while iterating.\n\n#### IteratorWithIndex\n\nAn [iterator](#iterator) whose elements are referenced by an index.\n\nTypical usage:\n```go\nit := list.Iterator()\nfor it.Next() {\n\tindex, value := it.Index(), it.Value()\n\t...\n}\n```\n\nOther usages:\n```go\nif it.First() {\n\tfirstIndex, firstValue := it.Index(), it.Value()\n\t...\n}\n```\n\n```go\nfor it.Begin(); it.Next(); {\n\t...\n}\n```\n\nSeeking to a specific element:\n\n```go\n// Seek function, i.e. find element starting with \"b\"\nseek := func(index int, value interface{}) bool {\n    return strings.HasSuffix(value.(string), \"b\")\n}\n\n// Seek to the condition and continue traversal from that point (forward).\n// assumes it.Begin() was called.\nfor found := it.NextTo(seek); found; found = it.Next() {\n    index, value := it.Index(), it.Value()\n    ...\n}\n```\n\n#### IteratorWithKey\n\nAn [iterator](#iterator) whose elements are referenced by a key.\n\nTypical usage:\n```go\nit := tree.Iterator()\nfor it.Next() {\n\tkey, value := it.Key(), it.Value()\n\t...\n}\n```\n\nOther usages:\n```go\nif it.First() {\n\tfirstKey, firstValue := it.Key(), it.Value()\n\t...\n}\n```\n\n```go\nfor it.Begin(); it.Next(); {\n\t...\n}\n```\n\nSeeking to a specific element from the current iterator position:\n\n```go\n// Seek function, i.e. find element starting with \"b\"\nseek := func(key interface{}, value interface{}) bool {\n    return strings.HasSuffix(value.(string), \"b\")\n}\n\n// Seek to the condition and continue traversal from that point (forward).\n// assumes it.Begin() was called.\nfor found := it.NextTo(seek); found; found = it.Next() {\n    key, value := it.Key(), it.Value()\n    ...\n}\n```\n\n#### ReverseIteratorWithIndex\n\nAn [iterator](#iterator) whose elements are referenced by an index. Provides all functions as [IteratorWithIndex](#iteratorwithindex), but can also be used for reverse iteration.\n\nTypical usage of iteration in reverse:\n```go\nit := list.Iterator()\nfor it.End(); it.Prev(); {\n\tindex, value := it.Index(), it.Value()\n\t...\n}\n```\n\nOther usages:\n```go\nif it.Last() {\n\tlastIndex, lastValue := it.Index(), it.Value()\n\t...\n}\n```\n\nSeeking to a specific element:\n\n```go\n// Seek function, i.e. find element starting with \"b\"\nseek := func(index int, value interface{}) bool {\n    return strings.HasSuffix(value.(string), \"b\")\n}\n\n// Seek to the condition and continue traversal from that point (in reverse).\n// assumes it.End() was called.\nfor found := it.PrevTo(seek); found; found = it.Prev() {\n    index, value := it.Index(), it.Value()\n\t...\n}\n```\n\n#### ReverseIteratorWithKey\n\nAn [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration.\n\nTypical usage of iteration in reverse:\n```go\nit := tree.Iterator()\nfor it.End(); it.Prev(); {\n\tkey, value := it.Key(), it.Value()\n\t...\n}\n```\n\nOther usages:\n```go\nif it.Last() {\n\tlastKey, lastValue := it.Key(), it.Value()\n\t...\n}\n```\n\n```go\n// Seek function, i.e. find element starting with \"b\"\nseek := func(key interface{}, value interface{}) bool {\n    return strings.HasSuffix(value.(string), \"b\")\n}\n\n// Seek to the condition and continue traversal from that point (in reverse).\n// assumes it.End() was called.\nfor found := it.PrevTo(seek); found; found = it.Prev() {\n    key, value := it.Key(), it.Value()\n\t...\n}\n```\n\n### Enumerable\n\nEnumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces.\n\n#### EnumerableWithIndex\n\n[Enumerable](#enumerable) functions for ordered containers whose values can be fetched by an index.\n\n**Each**\n\nCalls the given function once for each element, passing that element's index and value.\n\n```go\nEach(func(index int, value interface{}))\n```\n\n**Map**\n\nInvokes the given function once for each element and returns a container containing the values returned by the given function.\n\n```go\nMap(func(index int, value interface{}) interface{}) Container\n```\n\n**Select**\n\nReturns a new container containing all elements for which the given function returns a true value.\n\n```go\nSelect(func(index int, value interface{}) bool) Container\n```\n\n**Any**\n\nPasses each element of the container to the given function and returns true if the function ever returns true for any element.\n\n```go\nAny(func(index int, value interface{}) bool) bool\n```\n\n**All**\n\nPasses each element of the container to the given function and returns true if the function returns true for all elements.\n\n```go\nAll(func(index int, value interface{}) bool) bool\n```\n\n**Find**\n\nPasses 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.\n\n```go\nFind(func(index int, value interface{}) bool) (int, interface{})}\n```\n\n**Example:**\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/sets/treeset\"\n)\n\nfunc printSet(txt string, set *treeset.Set) {\n\tfmt.Print(txt, \"[ \")\n\tset.Each(func(index int, value interface{}) {\n\t\tfmt.Print(value, \" \")\n\t})\n\tfmt.Println(\"]\")\n}\n\nfunc main() {\n\tset := treeset.NewWithIntComparator()\n\tset.Add(2, 3, 4, 2, 5, 6, 7, 8)\n\tprintSet(\"Initial\", set) // [ 2 3 4 5 6 7 8 ]\n\n\teven := set.Select(func(index int, value interface{}) bool {\n\t\treturn value.(int)%2 == 0\n\t})\n\tprintSet(\"Even numbers\", even) // [ 2 4 6 8 ]\n\n\tfoundIndex, foundValue := set.Find(func(index int, value interface{}) bool {\n\t\treturn value.(int)%2 == 0 && value.(int)%3 == 0\n\t})\n\tif foundIndex != -1 {\n\t\tfmt.Println(\"Number divisible by 2 and 3 found is\", foundValue, \"at index\", foundIndex) // value: 6, index: 4\n\t}\n\n\tsquare := set.Map(func(index int, value interface{}) interface{} {\n\t\treturn value.(int) * value.(int)\n\t})\n\tprintSet(\"Numbers squared\", square) // [ 4 9 16 25 36 49 64 ]\n\n\tbigger := set.Any(func(index int, value interface{}) bool {\n\t\treturn value.(int) > 5\n\t})\n\tfmt.Println(\"Set contains a number bigger than 5 is \", bigger) // true\n\n\tpositive := set.All(func(index int, value interface{}) bool {\n\t\treturn value.(int) > 0\n\t})\n\tfmt.Println(\"All numbers are positive is\", positive) // true\n\n\tevenNumbersSquared := set.Select(func(index int, value interface{}) bool {\n\t\treturn value.(int)%2 == 0\n\t}).Map(func(index int, value interface{}) interface{} {\n\t\treturn value.(int) * value.(int)\n\t})\n\tprintSet(\"Chaining\", evenNumbersSquared) // [ 4 16 36 64 ]\n}\n```\n\n#### EnumerableWithKey\n\nEnumerable functions for ordered containers whose values whose elements are key/value pairs.\n\n**Each**\n\nCalls the given function once for each element, passing that element's key and value.\n\n```go\nEach(func(key interface{}, value interface{}))\n```\n\n**Map**\n\nInvokes the given function once for each element and returns a container containing the values returned by the given function as key/value pairs.\n\n```go\nMap(func(key interface{}, value interface{}) (interface{}, interface{})) Container\n```\n\n**Select**\n\nReturns a new container containing all elements for which the given function returns a true value.\n\n```go\nSelect(func(key interface{}, value interface{}) bool) Container\n```\n\n**Any**\n\nPasses each element of the container to the given function and returns true if the function ever returns true for any element.\n\n```go\nAny(func(key interface{}, value interface{}) bool) bool\n```\n\n**All**\n\nPasses each element of the container to the given function and returns true if the function returns true for all elements.\n\n```go\nAll(func(key interface{}, value interface{}) bool) bool\n```\n\n**Find**\n\nPasses 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.\n\n```go\nFind(func(key interface{}, value interface{}) bool) (interface{}, interface{})\n```\n\n**Example:**\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/maps/treemap\"\n)\n\nfunc printMap(txt string, m *treemap.Map) {\n\tfmt.Print(txt, \" { \")\n\tm.Each(func(key interface{}, value interface{}) {\n\t\tfmt.Print(key, \":\", value, \" \")\n\t})\n\tfmt.Println(\"}\")\n}\n\nfunc main() {\n\tm := treemap.NewWithStringComparator()\n\tm.Put(\"g\", 7)\n\tm.Put(\"f\", 6)\n\tm.Put(\"e\", 5)\n\tm.Put(\"d\", 4)\n\tm.Put(\"c\", 3)\n\tm.Put(\"b\", 2)\n\tm.Put(\"a\", 1)\n\tprintMap(\"Initial\", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 }\n\n\teven := m.Select(func(key interface{}, value interface{}) bool {\n\t\treturn value.(int) % 2 == 0\n\t})\n\tprintMap(\"Elements with even values\", even) // { b:2 d:4 f:6 }\n\n\tfoundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool {\n\t\treturn value.(int) % 2 == 0 && value.(int) % 3 == 0\n\t})\n\tif foundKey != nil {\n\t\tfmt.Println(\"Element with value divisible by 2 and 3 found is\", foundValue, \"with key\", foundKey) // value: 6, index: 4\n\t}\n\n\tsquare := m.Map(func(key interface{}, value interface{}) (interface{}, interface{}) {\n\t\treturn key.(string) + key.(string), value.(int) * value.(int)\n\t})\n\tprintMap(\"Elements' values squared and letters duplicated\", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 }\n\n\tbigger := m.Any(func(key interface{}, value interface{}) bool {\n\t\treturn value.(int) > 5\n\t})\n\tfmt.Println(\"Map contains element whose value is bigger than 5 is\", bigger) // true\n\n\tpositive := m.All(func(key interface{}, value interface{}) bool {\n\t\treturn value.(int) > 0\n\t})\n\tfmt.Println(\"All map's elements have positive values is\", positive) // true\n\n\tevenNumbersSquared := m.Select(func(key interface{}, value interface{}) bool {\n\t\treturn value.(int) % 2 == 0\n\t}).Map(func(key interface{}, value interface{}) (interface{}, interface{}) {\n\t\treturn key, value.(int) * value.(int)\n\t})\n\tprintMap(\"Chaining\", evenNumbersSquared) // { b:4 d:16 f:36 }\n}\n```\n\n### Serialization\n\nAll data structures can be serialized (marshalled) and deserialized (unmarshalled). Currently, only JSON support is available.\n\n#### JSONSerializer\n\nOutputs the container into its JSON representation.\n\nTypical usage for key-value structures:\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/maps/hashmap\"\n)\n\nfunc main() {\n\tm := hashmap.New()\n\tm.Put(\"a\", \"1\")\n\tm.Put(\"b\", \"2\")\n\tm.Put(\"c\", \"3\")\n\n\tbytes, err := json.Marshal(m) // Same as \"m.ToJSON(m)\"\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(string(bytes)) // {\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}\n}\n```\n\nTypical usage for value-only structures:\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/lists/arraylist\"\n)\n\nfunc main() {\n\tlist := arraylist.New()\n\tlist.Add(\"a\", \"b\", \"c\")\n\n\tbytes, err := json.Marshal(list) // Same as \"list.ToJSON(list)\"\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(string(bytes)) // [\"a\",\"b\",\"c\"]\n}\n```\n\n#### JSONDeserializer\n\nPopulates the container with elements from the input JSON representation.\n\nTypical usage for key-value structures:\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/maps/hashmap\"\n)\n\nfunc main() {\n\thm := hashmap.New()\n\n\tbytes := []byte(`{\"a\":\"1\",\"b\":\"2\"}`)\n\terr := json.Unmarshal(bytes, &hm) // Same as \"hm.FromJSON(bytes)\"\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(hm) // HashMap map[b:2 a:1]\n}\n```\n\nTypical usage for value-only structures:\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/emirpasic/gods/lists/arraylist\"\n)\n\nfunc main() {\n\tlist := arraylist.New()\n\n\tbytes := []byte(`[\"a\",\"b\"]`)\n\terr := json.Unmarshal(bytes, &list) // Same as \"list.FromJSON(bytes)\"\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(list) // ArrayList [\"a\",\"b\"]\n}\n```\n\n### Sort\n\nSort is a general purpose sort function.\n\nLists have an in-place _Sort()_ function and all containers can return their sorted elements via _containers.GetSortedValues()_ function.\n\nInternally these all use the _utils.Sort()_ method:\n\n```go\npackage main\n\nimport \"github.com/emirpasic/gods/utils\"\n\nfunc main() {\n\tstrings := []interface{}{}                  // []\n\tstrings = append(strings, \"d\")              // [\"d\"]\n\tstrings = append(strings, \"a\")              // [\"d\",\"a\"]\n\tstrings = append(strings, \"b\")              // [\"d\",\"a\",b\"\n\tstrings = append(strings, \"c\")              // [\"d\",\"a\",b\",\"c\"]\n\tutils.Sort(strings, utils.StringComparator) // [\"a\",\"b\",\"c\",\"d\"]\n}\n```\n\n### Container\n\nContainer specific operations:\n\n```go\n// Returns sorted container''s elements with respect to the passed comparator.\n// Does not affect the ordering of elements within the container.\nfunc GetSortedValues(container Container, comparator utils.Comparator) []interface{}\n```\n\nUsage:\n\n```go\npackage main\n\nimport (\n\t\"github.com/emirpasic/gods/lists/arraylist\"\n\t\"github.com/emirpasic/gods/utils\"\n)\n\nfunc main() {\n\tlist := arraylist.New()\n\tlist.Add(2, 1, 3)\n\tvalues := GetSortedValues(container, utils.StringComparator) // [1, 2, 3]\n}\n```\n\n## Appendix\n\n### Motivation\n\nCollections and data structures found in other languages: Java Collections, C++ Standard Template Library (STL) containers, Qt Containers, Ruby Enumerable etc.\n\n### Goals\n\n**Fast algorithms**:\n\n  - Based on decades of knowledge and experiences of other libraries mentioned above.\n\n**Memory efficient algorithms**:\n\n  - 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.\n\n**Easy to use library**:\n\n  - Well-structured library with minimalistic set of atomic operations from which more complex operations can be crafted.\n\n**Stable library**:\n\n  - Only additions are permitted keeping the library backward compatible.\n\n**Solid documentation and examples**:\n\n  - Learning by example.\n\n**Production ready**:\n\n  - Used in production.\n\n**No dependencies**:\n\n  - No external imports.\n\nThere 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.\n\nThread safety is not a concern of this project, this should be handled at a higher level.\n\n### Testing and Benchmarking\n\nThis takes a while, so test within sub-packages:\n\n`go test -run=NO_TEST -bench . -benchmem  -benchtime 1s ./...`\n\n<p align=\"center\"><img src=\"https://cloud.githubusercontent.com/assets/3115942/16892979/5e698d46-4b27-11e6-864b-cb2b865327b6.png\" /></p>\n\n### Contributing\n\nBiggest contribution towards this library is to use it and give us feedback for further improvements and additions.\n\nFor direct contributions, _pull request_ into master branch or ask to become a contributor.\n\nCoding style:\n\n```shell\n# Install tooling and set path:\ngo install gotest.tools/gotestsum@latest\ngo install golang.org/x/lint/golint@latest\ngo install github.com/kisielk/errcheck@latest\nexport PATH=$PATH:$GOPATH/bin\n\n# Fix errors and warnings:\ngo fmt ./... &&\ngo test -v ./... && \ngolint -set_exit_status ./... && \n! go fmt ./... 2>&1 | read &&\ngo vet -v ./... &&\ngocyclo -avg -over 15 ../gods &&\nerrcheck ./...\n```\n\n### License\n\nThis library is distributed under the BSD-style license found in the [LICENSE](https://github.com/emirpasic/gods/blob/master/LICENSE) file.\n\n### Sponsors\n\n## <a href=\"https://www.browserstack.com/?ref=gods\"><img src=\"http://www.hajdarevic.net/browserstack.svg\" alt=\"BrowserStack\" width=\"250\"/></a>\n[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.\n"
  },
  {
    "path": "containers/containers.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package containers provides core interfaces and functions for data structures.\n//\n// Container is the base interface for all data structures to implement.\n//\n// Iterators provide stateful iterators.\n//\n// Enumerable provides Ruby inspired (each, select, map, find, any?, etc.) container functions.\n//\n// Serialization provides serializers (marshalers) and deserializers (unmarshalers).\npackage containers\n\nimport (\n\t\"cmp\"\n\t\"slices\"\n\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Container is base interface that all data structures implement.\ntype Container[T any] interface {\n\tEmpty() bool\n\tSize() int\n\tClear()\n\tValues() []T\n\tString() string\n}\n\n// GetSortedValues returns sorted container's elements with respect to the passed comparator.\n// Does not affect the ordering of elements within the container.\nfunc GetSortedValues[T cmp.Ordered](container Container[T]) []T {\n\tvalues := container.Values()\n\tif len(values) < 2 {\n\t\treturn values\n\t}\n\tslices.Sort(values)\n\treturn values\n}\n\n// GetSortedValuesFunc is the equivalent of GetSortedValues for containers of values that are not ordered.\nfunc GetSortedValuesFunc[T any](container Container[T], comparator utils.Comparator[T]) []T {\n\tvalues := container.Values()\n\tif len(values) < 2 {\n\t\treturn values\n\t}\n\tslices.SortFunc(values, comparator)\n\treturn values\n}\n"
  },
  {
    "path": "containers/containers_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// All data structures must implement the container structure\n\npackage containers\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n)\n\n// For testing purposes\ntype ContainerTest[T any] struct {\n\tvalues []T\n}\n\nfunc (container ContainerTest[T]) Empty() bool {\n\treturn len(container.values) == 0\n}\n\nfunc (container ContainerTest[T]) Size() int {\n\treturn len(container.values)\n}\n\nfunc (container ContainerTest[T]) Clear() {\n\tcontainer.values = []T{}\n}\n\nfunc (container ContainerTest[T]) Values() []T {\n\treturn container.values\n}\n\nfunc (container ContainerTest[T]) String() string {\n\tstr := \"ContainerTest\\n\"\n\tvar values []string\n\tfor _, value := range container.values {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\nfunc TestGetSortedValuesInts(t *testing.T) {\n\tcontainer := ContainerTest[int]{}\n\tGetSortedValues(container)\n\tcontainer.values = []int{5, 1, 3, 2, 4}\n\tvalues := GetSortedValues(container)\n\tfor i := 1; i < container.Size(); i++ {\n\t\tif values[i-1] > values[i] {\n\t\t\tt.Errorf(\"Not sorted!\")\n\t\t}\n\t}\n}\n\ntype NotInt struct {\n\ti int\n}\n\nfunc TestGetSortedValuesNotInts(t *testing.T) {\n\tcontainer := ContainerTest[NotInt]{}\n\tGetSortedValuesFunc(container, func(x, y NotInt) int {\n\t\treturn cmp.Compare(x.i, y.i)\n\t})\n\tcontainer.values = []NotInt{{5}, {1}, {3}, {2}, {4}}\n\tvalues := GetSortedValuesFunc(container, func(x, y NotInt) int {\n\t\treturn cmp.Compare(x.i, y.i)\n\t})\n\tfor i := 1; i < container.Size(); i++ {\n\t\tif values[i-1].i > values[i].i {\n\t\t\tt.Errorf(\"Not sorted!\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "containers/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage containers\n\n// EnumerableWithIndex provides functions for ordered containers whose values can be fetched by an index.\ntype EnumerableWithIndex[T any] interface {\n\t// Each calls the given function once for each element, passing that element's index and value.\n\tEach(func(index int, value T))\n\n\t// Map invokes the given function once for each element and returns a\n\t// container containing the values returned by the given function.\n\t// Map(func(index int, value interface{}) interface{}) Container\n\n\t// Select returns a new container containing all elements for which the given function returns a true value.\n\t// Select(func(index int, value interface{}) bool) Container\n\n\t// Any passes each element of the container to the given function and\n\t// returns true if the function ever returns true for any element.\n\tAny(func(index int, value T) bool) bool\n\n\t// All passes each element of the container to the given function and\n\t// returns true if the function returns true for all elements.\n\tAll(func(index int, value T) bool) bool\n\n\t// Find passes each element of the container to the given function and returns\n\t// the first (index,value) for which the function is true or -1,nil otherwise\n\t// if no element matches the criteria.\n\tFind(func(index int, value T) bool) (int, T)\n}\n\n// EnumerableWithKey provides functions for ordered containers whose values whose elements are key/value pairs.\ntype EnumerableWithKey[K, V any] interface {\n\t// Each calls the given function once for each element, passing that element's key and value.\n\tEach(func(key K, value V))\n\n\t// Map invokes the given function once for each element and returns a container\n\t// containing the values returned by the given function as key/value pairs.\n\t// Map(func(key interface{}, value interface{}) (interface{}, interface{})) Container\n\n\t// Select returns a new container containing all elements for which the given function returns a true value.\n\t// Select(func(key interface{}, value interface{}) bool) Container\n\n\t// Any passes each element of the container to the given function and\n\t// returns true if the function ever returns true for any element.\n\tAny(func(key K, value V) bool) bool\n\n\t// All passes each element of the container to the given function and\n\t// returns true if the function returns true for all elements.\n\tAll(func(key K, value V) bool) bool\n\n\t// Find passes each element of the container to the given function and returns\n\t// the first (key,value) for which the function is true or nil,nil otherwise if no element\n\t// matches the criteria.\n\tFind(func(key K, value V) bool) (K, V)\n}\n"
  },
  {
    "path": "containers/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage containers\n\n// IteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.\ntype IteratorWithIndex[T any] interface {\n\t// Next moves the iterator to the next element and returns true if there was a next element in the container.\n\t// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n\t// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n\t// Modifies the state of the iterator.\n\tNext() bool\n\n\t// Value returns the current element's value.\n\t// Does not modify the state of the iterator.\n\tValue() T\n\n\t// Index returns the current element's index.\n\t// Does not modify the state of the iterator.\n\tIndex() int\n\n\t// Begin resets the iterator to its initial state (one-before-first)\n\t// Call Next() to fetch the first element if any.\n\tBegin()\n\n\t// First moves the iterator to the first element and returns true if there was a first element in the container.\n\t// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n\t// Modifies the state of the iterator.\n\tFirst() bool\n\n\t// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n\t// passed function, and returns true if there was a next element in the container.\n\t// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n\t// Modifies the state of the iterator.\n\tNextTo(func(index int, value T) bool) bool\n}\n\n// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.\ntype IteratorWithKey[K, V any] interface {\n\t// Next moves the iterator to the next element and returns true if there was a next element in the container.\n\t// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n\t// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n\t// Modifies the state of the iterator.\n\tNext() bool\n\n\t// Value returns the current element's value.\n\t// Does not modify the state of the iterator.\n\tValue() V\n\n\t// Key returns the current element's key.\n\t// Does not modify the state of the iterator.\n\tKey() K\n\n\t// Begin resets the iterator to its initial state (one-before-first)\n\t// Call Next() to fetch the first element if any.\n\tBegin()\n\n\t// First moves the iterator to the first element and returns true if there was a first element in the container.\n\t// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n\t// Modifies the state of the iterator.\n\tFirst() bool\n\n\t// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n\t// passed function, and returns true if there was a next element in the container.\n\t// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n\t// Modifies the state of the iterator.\n\tNextTo(func(key K, value V) bool) bool\n}\n\n// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.\n//\n// Essentially it is the same as IteratorWithIndex, but provides additional:\n//\n// # Prev() function to enable traversal in reverse\n//\n// Last() function to move the iterator to the last element.\n//\n// End() function to move the iterator past the last element (one-past-the-end).\ntype ReverseIteratorWithIndex[T any] interface {\n\t// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n\t// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n\t// Modifies the state of the iterator.\n\tPrev() bool\n\n\t// End moves the iterator past the last element (one-past-the-end).\n\t// Call Prev() to fetch the last element if any.\n\tEnd()\n\n\t// Last moves the iterator to the last element and returns true if there was a last element in the container.\n\t// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n\t// Modifies the state of the iterator.\n\tLast() bool\n\n\t// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n\t// passed function, and returns true if there was a next element in the container.\n\t// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n\t// Modifies the state of the iterator.\n\tPrevTo(func(index int, value T) bool) bool\n\n\tIteratorWithIndex[T]\n}\n\n// ReverseIteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.\n//\n// Essentially it is the same as IteratorWithKey, but provides additional:\n//\n// # Prev() function to enable traversal in reverse\n//\n// Last() function to move the iterator to the last element.\ntype ReverseIteratorWithKey[K, V any] interface {\n\t// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n\t// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().\n\t// Modifies the state of the iterator.\n\tPrev() bool\n\n\t// End moves the iterator past the last element (one-past-the-end).\n\t// Call Prev() to fetch the last element if any.\n\tEnd()\n\n\t// Last moves the iterator to the last element and returns true if there was a last element in the container.\n\t// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n\t// Modifies the state of the iterator.\n\tLast() bool\n\n\t// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n\t// passed function, and returns true if there was a next element in the container.\n\t// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n\t// Modifies the state of the iterator.\n\tPrevTo(func(key K, value V) bool) bool\n\n\tIteratorWithKey[K, V]\n}\n"
  },
  {
    "path": "containers/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage containers\n\n// JSONSerializer provides JSON serialization\ntype JSONSerializer interface {\n\t// ToJSON outputs the JSON representation of containers's elements.\n\tToJSON() ([]byte, error)\n\t// MarshalJSON @implements json.Marshaler\n\tMarshalJSON() ([]byte, error)\n}\n\n// JSONDeserializer provides JSON deserialization\ntype JSONDeserializer interface {\n\t// FromJSON populates containers's elements from the input JSON representation.\n\tFromJSON([]byte) error\n\t// UnmarshalJSON @implements json.Unmarshaler\n\tUnmarshalJSON([]byte) error\n}\n"
  },
  {
    "path": "examples/README.md",
    "content": "# GoDS (Go Data Structures)\n\nVarious examples on how to use data structures.\n\n## Examples\n\n- [ArrayList](https://github.com/emirpasic/gods/blob/master/examples/arraylist/arraylist.go)\n- [ArrayStack](https://github.com/emirpasic/gods/blob/master/examples/arraystack/arraystack.go)\n- [AVLTree](https://github.com/emirpasic/gods/blob/master/examples/avltree/avltree.go)\n- [BinaryHeap](https://github.com/emirpasic/gods/blob/master/examples/binaryheap/binaryheap.go)\n- [BTree](https://github.com/emirpasic/gods/blob/master/examples/btree/btree.go)\n- [Custom Comparator](https://github.com/emirpasic/gods/blob/master/examples/customcomparator/customcomparator.go)\n- [DoublyLinkedList](https://github.com/emirpasic/gods/blob/master/examples/doublylinkedlist/doublylinkedlist.go)\n- [EnumerableWithIndex](https://github.com/emirpasic/gods/blob/master/examples/enumerablewithindex/enumerablewithindex.go)\n- [EnumerableWithKey](https://github.com/emirpasic/gods/blob/master/examples/enumerablewithkey/enumerablewithkey.go)\n- [HashBidiMap](https://github.com/emirpasic/gods/blob/master/examples/hashbidimap/hashbidimap.go)\n- [HashMap](https://github.com/emirpasic/gods/blob/master/examples/hashmap/hashmap.go)\n- [HashSet](https://github.com/emirpasic/gods/blob/master/examples/hashset/hashset.go)\n- [IteratorWithIndex](https://github.com/emirpasic/gods/blob/master/examples/iteratorwithindex/iteratorwithindex.go)\n- [iteratorwithkey](https://github.com/emirpasic/gods/blob/master/examples/iteratorwithkey/iteratorwithkey.go)\n- [IteratorWithKey](https://github.com/emirpasic/gods/blob/master/examples/linkedliststack/linkedliststack.go)\n- [RedBlackTree](https://github.com/emirpasic/gods/blob/master/examples/redblacktree/redblacktree.go)\n- [RedBlackTreeExtended](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended/redblacktreeextended.go)\n- [Serialization](https://github.com/emirpasic/gods/blob/master/examples/serialization/serialization.go)\n- [SinglyLinkedList](https://github.com/emirpasic/gods/blob/master/examples/singlylinkedlist/singlylinkedlist.go)\n- [Sort](https://github.com/emirpasic/gods/blob/master/examples/sort/sort.go)\n- [TreeBidiMap](https://github.com/emirpasic/gods/blob/master/examples/treebidimap/treebidimap.go)\n- [TreeMap](https://github.com/emirpasic/gods/blob/master/examples/treemap/treemap.go)\n- [TreeSet](https://github.com/emirpasic/gods/blob/master/examples/treeset/treeset.go)\n"
  },
  {
    "path": "examples/arraylist/arraylist.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"cmp\"\n\n\t\"github.com/emirpasic/gods/v2/lists/arraylist\"\n)\n\n// ArrayListExample to demonstrate basic usage of ArrayList\nfunc main() {\n\tlist := arraylist.New[string]()\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Add(\"c\", \"b\")                    // [\"a\",\"c\",\"b\"]\n\tlist.Sort(cmp.Compare[string])        // [\"a\",\"b\",\"c\"]\n\t_, _ = list.Get(0)                    // \"a\",true\n\t_, _ = list.Get(100)                  // nil,false\n\t_ = list.Contains(\"a\", \"b\", \"c\")      // true\n\t_ = list.Contains(\"a\", \"b\", \"c\", \"d\") // false\n\tlist.Swap(0, 1)                       // [\"b\",\"a\",c\"]\n\tlist.Remove(2)                        // [\"b\",\"a\"]\n\tlist.Remove(1)                        // [\"b\"]\n\tlist.Remove(0)                        // []\n\tlist.Remove(0)                        // [] (ignored)\n\t_ = list.Empty()                      // true\n\t_ = list.Size()                       // 0\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Clear()                          // []\n}\n"
  },
  {
    "path": "examples/arrayqueue/arrayqqueue.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport aq \"github.com/emirpasic/gods/v2/queues/arrayqueue\"\n\n// ArrayQueueExample to demonstrate basic usage of ArrayQueue\nfunc main() {\n\tqueue := aq.New[int]() // empty\n\tqueue.Enqueue(1)       // 1\n\tqueue.Enqueue(2)       // 1, 2\n\t_ = queue.Values()     // 1, 2 (FIFO order)\n\t_, _ = queue.Peek()    // 1,true\n\t_, _ = queue.Dequeue() // 1, true\n\t_, _ = queue.Dequeue() // 2, true\n\t_, _ = queue.Dequeue() // nil, false (nothing to deque)\n\tqueue.Enqueue(1)       // 1\n\tqueue.Clear()          // empty\n\tqueue.Empty()          // true\n\t_ = queue.Size()       // 0\n}\n"
  },
  {
    "path": "examples/arraystack/arraystack.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/stacks/arraystack\"\n\n// ArrayStackExample to demonstrate basic usage of ArrayStack\nfunc main() {\n\tstack := arraystack.New[int]() // empty\n\tstack.Push(1)                  // 1\n\tstack.Push(2)                  // 1, 2\n\tstack.Values()                 // 2, 1 (LIFO order)\n\t_, _ = stack.Peek()            // 2,true\n\t_, _ = stack.Pop()             // 2, true\n\t_, _ = stack.Pop()             // 1, true\n\t_, _ = stack.Pop()             // nil, false (nothing to pop)\n\tstack.Push(1)                  // 1\n\tstack.Clear()                  // empty\n\tstack.Empty()                  // true\n\tstack.Size()                   // 0\n}\n"
  },
  {
    "path": "examples/avltree/avltree.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\n\tavl \"github.com/emirpasic/gods/v2/trees/avltree\"\n)\n\n// AVLTreeExample to demonstrate basic usage of AVLTree\nfunc main() {\n\ttree := avl.New[int, string]() // empty(keys are of type int)\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\n\tfmt.Println(tree)\n\t//\n\t//  AVLTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      │   ┌── 3\n\t//      └── 2\n\t//          └── 1\n\n\t_ = tree.Values() // []interface {}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"} (in order)\n\t_ = tree.Keys()   // []interface {}{1, 2, 3, 4, 5, 6} (in order)\n\n\ttree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)\n\tfmt.Println(tree)\n\t//\n\t//  AVLTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      └── 3\n\t//          └── 1\n\n\ttree.Clear() // empty\n\ttree.Empty() // true\n\ttree.Size()  // 0\n}\n"
  },
  {
    "path": "examples/binaryheap/binaryheap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"cmp\"\n\n\t\"github.com/emirpasic/gods/v2/trees/binaryheap\"\n)\n\n// BinaryHeapExample to demonstrate basic usage of BinaryHeap\nfunc main() {\n\n\t// Min-heap\n\theap := binaryheap.New[int]() // empty (min-heap)\n\theap.Push(2)                  // 2\n\theap.Push(3)                  // 2, 3\n\theap.Push(1)                  // 1, 3, 2\n\theap.Values()                 // 1, 3, 2\n\t_, _ = heap.Peek()            // 1,true\n\t_, _ = heap.Pop()             // 1, true\n\t_, _ = heap.Pop()             // 2, true\n\t_, _ = heap.Pop()             // 3, true\n\t_, _ = heap.Pop()             // nil, false (nothing to pop)\n\theap.Push(1)                  // 1\n\theap.Clear()                  // empty\n\theap.Empty()                  // true\n\theap.Size()                   // 0\n\n\t// Max-heap\n\tinverseIntComparator := func(a, b int) int {\n\t\treturn -cmp.Compare(a, b)\n\t}\n\theap = binaryheap.NewWith(inverseIntComparator) // empty (min-heap)\n\theap.Push(2)                                    // 2\n\theap.Push(3)                                    // 3, 2\n\theap.Push(1)                                    // 3, 2, 1\n\theap.Values()                                   // 3, 2, 1\n}\n"
  },
  {
    "path": "examples/btree/btree.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/trees/btree\"\n)\n\n// BTreeExample to demonstrate basic usage of BTree\nfunc main() {\n\ttree := btree.New[int, string](3) // empty (keys are of type int)\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\ttree.Put(7, \"g\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order)\n\n\tfmt.Println(tree)\n\t// BTree\n\t//         1\n\t//     2\n\t//         3\n\t// 4\n\t//         5\n\t//     6\n\t//         7\n\n\t_ = tree.Values() // []interface {}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"} (in order)\n\t_ = tree.Keys()   // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order)\n\n\ttree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)\n\tfmt.Println(tree)\n\t// BTree\n\t//     1\n\t//     3\n\t// 4\n\t//     5\n\t//     6\n\n\ttree.Clear() // empty\n\ttree.Empty() // true\n\ttree.Size()  // 0\n\n\t// Other:\n\ttree.Height()     // gets the height of the tree\n\ttree.Left()       // gets the left-most (min) node\n\ttree.LeftKey()    // get the left-most (min) node's key\n\ttree.LeftValue()  // get the left-most (min) node's value\n\ttree.Right()      // get the right-most (max) node\n\ttree.RightKey()   // get the right-most (max) node's key\n\ttree.RightValue() // get the right-most (max) node's value\n}\n"
  },
  {
    "path": "examples/circularbuffer/circularbuffer.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport cb \"github.com/emirpasic/gods/v2/queues/circularbuffer\"\n\n// CircularBufferExample to demonstrate basic usage of CircularBuffer\nfunc main() {\n\tqueue := cb.New[int](3) // empty (max size is 3)\n\tqueue.Enqueue(1)        // 1\n\tqueue.Enqueue(2)        // 1, 2\n\tqueue.Enqueue(3)        // 1, 2, 3\n\t_ = queue.Values()      // 1, 2, 3\n\tqueue.Enqueue(3)        // 4, 2, 3\n\t_, _ = queue.Peek()     // 4,true\n\t_, _ = queue.Dequeue()  // 4, true\n\t_, _ = queue.Dequeue()  // 2, true\n\t_, _ = queue.Dequeue()  // 3, true\n\t_, _ = queue.Dequeue()  // nil, false (nothing to deque)\n\tqueue.Enqueue(1)        // 1\n\tqueue.Clear()           // empty\n\tqueue.Empty()           // true\n\t_ = queue.Size()        // 0\n}\n"
  },
  {
    "path": "examples/customcomparator/customcomparator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/sets/treeset\"\n)\n\n// User model (id and name)\ntype User struct {\n\tid   int\n\tname string\n}\n\n// Comparator function (sort by IDs)\nfunc byID(a, b User) int {\n\n\tswitch {\n\tcase a.id > b.id:\n\t\treturn 1\n\tcase a.id < b.id:\n\t\treturn -1\n\tdefault:\n\t\treturn 0\n\t}\n}\n\n// CustomComparatorExample to demonstrate basic usage of CustomComparator\nfunc main() {\n\tset := treeset.NewWith(byID)\n\n\tset.Add(User{2, \"Second\"})\n\tset.Add(User{3, \"Third\"})\n\tset.Add(User{1, \"First\"})\n\tset.Add(User{4, \"Fourth\"})\n\n\tfmt.Println(set) // {1 First}, {2 Second}, {3 Third}, {4 Fourth}\n}\n"
  },
  {
    "path": "examples/doublylinkedlist/doublylinkedlist.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"cmp\"\n\n\tdll \"github.com/emirpasic/gods/v2/lists/doublylinkedlist\"\n)\n\n// DoublyLinkedListExample to demonstrate basic usage of DoublyLinkedList\nfunc main() {\n\tlist := dll.New[string]()\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Append(\"b\")                      // [\"a\",\"b\"] (same as Add())\n\tlist.Prepend(\"c\")                     // [\"c\",\"a\",\"b\"]\n\tlist.Sort(cmp.Compare[string])        // [\"a\",\"b\",\"c\"]\n\t_, _ = list.Get(0)                    // \"a\",true\n\t_, _ = list.Get(100)                  // nil,false\n\t_ = list.Contains(\"a\", \"b\", \"c\")      // true\n\t_ = list.Contains(\"a\", \"b\", \"c\", \"d\") // false\n\tlist.Remove(2)                        // [\"a\",\"b\"]\n\tlist.Remove(1)                        // [\"a\"]\n\tlist.Remove(0)                        // []\n\tlist.Remove(0)                        // [] (ignored)\n\t_ = list.Empty()                      // true\n\t_ = list.Size()                       // 0\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Clear()                          // []\n}\n"
  },
  {
    "path": "examples/enumerablewithindex/enumerablewithindex.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/sets/treeset\"\n)\n\nfunc printSet(txt string, set *treeset.Set[int]) {\n\tfmt.Print(txt, \"[ \")\n\tset.Each(func(index int, value int) {\n\t\tfmt.Print(value, \" \")\n\t})\n\tfmt.Println(\"]\")\n}\n\n// EnumerableWithIndexExample to demonstrate basic usage of EnumerableWithIndex\nfunc main() {\n\tset := treeset.New[int]()\n\tset.Add(2, 3, 4, 2, 5, 6, 7, 8)\n\tprintSet(\"Initial\", set) // [ 2 3 4 5 6 7 8 ]\n\n\teven := set.Select(func(index int, value int) bool {\n\t\treturn value%2 == 0\n\t})\n\tprintSet(\"Even numbers\", even) // [ 2 4 6 8 ]\n\n\tfoundIndex, foundValue := set.Find(func(index int, value int) bool {\n\t\treturn value%2 == 0 && value%3 == 0\n\t})\n\tif foundIndex != -1 {\n\t\tfmt.Println(\"Number divisible by 2 and 3 found is\", foundValue, \"at index\", foundIndex) // value: 6, index: 4\n\t}\n\n\tsquare := set.Map(func(index int, value int) int {\n\t\treturn value * value\n\t})\n\tprintSet(\"Numbers squared\", square) // [ 4 9 16 25 36 49 64 ]\n\n\tbigger := set.Any(func(index int, value int) bool {\n\t\treturn value > 5\n\t})\n\tfmt.Println(\"Set contains a number bigger than 5 is \", bigger) // true\n\n\tpositive := set.All(func(index int, value int) bool {\n\t\treturn value > 0\n\t})\n\tfmt.Println(\"All numbers are positive is\", positive) // true\n\n\tevenNumbersSquared := set.Select(func(index int, value int) bool {\n\t\treturn value%2 == 0\n\t}).Map(func(index int, value int) int {\n\t\treturn value * value\n\t})\n\tprintSet(\"Chaining\", evenNumbersSquared) // [ 4 16 36 64 ]\n}\n"
  },
  {
    "path": "examples/enumerablewithkey/enumerablewithkey.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/maps/treemap\"\n)\n\nfunc printMap(txt string, m *treemap.Map[string, int]) {\n\tfmt.Print(txt, \" { \")\n\tm.Each(func(key string, value int) {\n\t\tfmt.Print(key, \":\", value, \" \")\n\t})\n\tfmt.Println(\"}\")\n}\n\n// EunumerableWithKeyExample to demonstrate basic usage of EunumerableWithKey\nfunc main() {\n\tm := treemap.New[string, int]()\n\tm.Put(\"g\", 7)\n\tm.Put(\"f\", 6)\n\tm.Put(\"e\", 5)\n\tm.Put(\"d\", 4)\n\tm.Put(\"c\", 3)\n\tm.Put(\"b\", 2)\n\tm.Put(\"a\", 1)\n\tprintMap(\"Initial\", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 }\n\n\teven := m.Select(func(key string, value int) bool {\n\t\treturn value%2 == 0\n\t})\n\tprintMap(\"Elements with even values\", even) // { b:2 d:4 f:6 }\n\n\tfoundKey, foundValue := m.Find(func(key string, value int) bool {\n\t\treturn value%2 == 0 && value%3 == 0\n\t})\n\tif foundKey != \"\" {\n\t\tfmt.Println(\"Element with value divisible by 2 and 3 found is\", foundValue, \"with key\", foundKey) // value: 6, index: 4\n\t}\n\n\tsquare := m.Map(func(key string, value int) (string, int) {\n\t\treturn key + key, value * value\n\t})\n\tprintMap(\"Elements' values squared and letters duplicated\", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 }\n\n\tbigger := m.Any(func(key string, value int) bool {\n\t\treturn value > 5\n\t})\n\tfmt.Println(\"Map contains element whose value is bigger than 5 is\", bigger) // true\n\n\tpositive := m.All(func(key string, value int) bool {\n\t\treturn value > 0\n\t})\n\tfmt.Println(\"All map's elements have positive values is\", positive) // true\n\n\tevenNumbersSquared := m.Select(func(key string, value int) bool {\n\t\treturn value%2 == 0\n\t}).Map(func(key string, value int) (string, int) {\n\t\treturn key, value * value\n\t})\n\tprintMap(\"Chaining\", evenNumbersSquared) // { b:4 d:16 f:36 }\n}\n"
  },
  {
    "path": "examples/hashbidimap/hashbidimap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/maps/hashbidimap\"\n\n// HashBidiMapExample to demonstrate basic usage of HashMap\nfunc main() {\n\tm := hashbidimap.New[int, string]() // empty\n\tm.Put(1, \"x\")                       // 1->x\n\tm.Put(3, \"b\")                       // 1->x, 3->b (random order)\n\tm.Put(1, \"a\")                       // 1->a, 3->b (random order)\n\tm.Put(2, \"b\")                       // 1->a, 2->b (random order)\n\t_, _ = m.GetKey(\"a\")                // 1, true\n\t_, _ = m.Get(2)                     // b, true\n\t_, _ = m.Get(3)                     // nil, false\n\t_ = m.Values()                      // []interface {}{\"a\", \"b\"} (random order)\n\t_ = m.Keys()                        // []interface {}{1, 2} (random order)\n\tm.Remove(1)                         // 2->b\n\tm.Clear()                           // empty\n\tm.Empty()                           // true\n\tm.Size()                            // 0\n}\n"
  },
  {
    "path": "examples/hashmap/hashmap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/maps/hashmap\"\n\n// HashMapExample to demonstrate basic usage of HashMap\nfunc main() {\n\tm := hashmap.New[int, string]() // empty\n\tm.Put(1, \"x\")                   // 1->x\n\tm.Put(2, \"b\")                   // 2->b, 1->x  (random order)\n\tm.Put(1, \"a\")                   // 2->b, 1->a (random order)\n\t_, _ = m.Get(2)                 // b, true\n\t_, _ = m.Get(3)                 // nil, false\n\t_ = m.Values()                  // []interface {}{\"b\", \"a\"} (random order)\n\t_ = m.Keys()                    // []interface {}{1, 2} (random order)\n\tm.Remove(1)                     // 2->b\n\tm.Clear()                       // empty\n\tm.Empty()                       // true\n\tm.Size()                        // 0\n}\n"
  },
  {
    "path": "examples/hashset/hashset.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/sets/hashset\"\n\n// HashSetExample to demonstrate basic usage of HashSet\nfunc main() {\n\tset := hashset.New[int]() // empty (keys are of type int)\n\tset.Add(1)                // 1\n\tset.Add(2, 2, 3, 4, 5)    // 3, 1, 2, 4, 5 (random order, duplicates ignored)\n\tset.Remove(4)             // 5, 3, 2, 1 (random order)\n\tset.Remove(2, 3)          // 1, 5 (random order)\n\tset.Contains(1)           // true\n\tset.Contains(1, 5)        // true\n\tset.Contains(1, 6)        // false\n\t_ = set.Values()          // []int{5,1} (random order)\n\tset.Clear()               // empty\n\tset.Empty()               // true\n\tset.Size()                // 0\n}\n"
  },
  {
    "path": "examples/iteratorwithindex/iteratorwithindex.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/sets/treeset\"\n)\n\n// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex\nfunc main() {\n\tset := treeset.New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\tit := set.Iterator()\n\n\tfmt.Print(\"\\nForward iteration\\n\")\n\tfor it.Next() {\n\t\tindex, value := it.Index(), it.Value()\n\t\tfmt.Print(\"[\", index, \":\", value, \"]\") // [0:a][1:b][2:c]\n\t}\n\n\tfmt.Print(\"\\nForward iteration (again)\\n\")\n\tfor it.Begin(); it.Next(); {\n\t\tindex, value := it.Index(), it.Value()\n\t\tfmt.Print(\"[\", index, \":\", value, \"]\") // [0:a][1:b][2:c]\n\t}\n\n\tfmt.Print(\"\\nBackward iteration\\n\")\n\tfor it.Prev() {\n\t\tindex, value := it.Index(), it.Value()\n\t\tfmt.Print(\"[\", index, \":\", value, \"]\") // [2:c][1:b][0:a]\n\t}\n\n\tfmt.Print(\"\\nBackward iteration (again)\\n\")\n\tfor it.End(); it.Prev(); {\n\t\tindex, value := it.Index(), it.Value()\n\t\tfmt.Print(\"[\", index, \":\", value, \"]\") // [2:c][1:b][0:a]\n\t}\n\n\tif it.First() {\n\t\tfmt.Print(\"\\nFirst index: \", it.Index()) // First index: 0\n\t\tfmt.Print(\"\\nFirst value: \", it.Value()) // First value: a\n\t}\n\n\tif it.Last() {\n\t\tfmt.Print(\"\\nLast index: \", it.Index()) // Last index: 3\n\t\tfmt.Print(\"\\nLast value: \", it.Value()) // Last value: c\n\t}\n\n\t// Seek element starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\tit.Begin()\n\tfor found := it.NextTo(seek); found; found = it.Next() {\n\t\tfmt.Print(\"\\nNextTo index: \", it.Index())\n\t\tfmt.Print(\"\\nNextTo value: \", it.Value())\n\t} /*\n\t\tNextTo index: 1\n\t\tNextTo value: \"b\"\n\t\tNextTo index: 2\n\t\tNextTo value: \"c\"\n\t*/\n\n\tit.End()\n\tfor found := it.PrevTo(seek); found; found = it.Prev() {\n\t\tfmt.Print(\"\\nNextTo index: \", it.Index())\n\t\tfmt.Print(\"\\nNextTo value: \", it.Value())\n\t} /*\n\t\tNextTo index: 1\n\t\tNextTo value: \"b\"\n\t\tNextTo index: 0\n\t\tNextTo value: \"a\"\n\t*/\n\n}\n"
  },
  {
    "path": "examples/iteratorwithkey/iteratorwithkey.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/maps/treemap\"\n)\n\n// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey\nfunc main() {\n\tm := treemap.New[int, string]()\n\tm.Put(0, \"a\")\n\tm.Put(1, \"b\")\n\tm.Put(2, \"c\")\n\tit := m.Iterator()\n\n\tfmt.Print(\"\\nForward iteration\\n\")\n\tfor it.Next() {\n\t\tkey, value := it.Key(), it.Value()\n\t\tfmt.Print(\"[\", key, \":\", value, \"]\") // [0:a][1:b][2:c]\n\t}\n\n\tfmt.Print(\"\\nForward iteration (again)\\n\")\n\tfor it.Begin(); it.Next(); {\n\t\tkey, value := it.Key(), it.Value()\n\t\tfmt.Print(\"[\", key, \":\", value, \"]\") // [0:a][1:b][2:c]\n\t}\n\n\tfmt.Print(\"\\nBackward iteration\\n\")\n\tfor it.Prev() {\n\t\tkey, value := it.Key(), it.Value()\n\t\tfmt.Print(\"[\", key, \":\", value, \"]\") // [2:c][1:b][0:a]\n\t}\n\n\tfmt.Print(\"\\nBackward iteration (again)\\n\")\n\tfor it.End(); it.Prev(); {\n\t\tkey, value := it.Key(), it.Value()\n\t\tfmt.Print(\"[\", key, \":\", value, \"]\") // [2:c][1:b][0:a]\n\t}\n\n\tif it.First() {\n\t\tfmt.Print(\"\\nFirst key: \", it.Key())     // First key: 0\n\t\tfmt.Print(\"\\nFirst value: \", it.Value()) // First value: a\n\t}\n\n\tif it.Last() {\n\t\tfmt.Print(\"\\nLast key: \", it.Key())     // Last key: 2\n\t\tfmt.Print(\"\\nLast value: \", it.Value()) // Last value: c\n\t}\n\n\t// Seek key-value pair whose value starts with \"b\"\n\tseek := func(key int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\tit.Begin()\n\tfor found := it.NextTo(seek); found; found = it.Next() {\n\t\tfmt.Print(\"\\nNextTo key: \", it.Key())\n\t\tfmt.Print(\"\\nNextTo value: \", it.Value())\n\t} /*\n\t\tNextTo key: 1\n\t\tNextTo value: \"b\"\n\t\tNextTo key: 2\n\t\tNextTo value: \"c\"\n\t*/\n\n\tit.End()\n\tfor found := it.PrevTo(seek); found; found = it.Prev() {\n\t\tfmt.Print(\"\\nNextTo key: \", it.Key())\n\t\tfmt.Print(\"\\nNextTo value: \", it.Value())\n\t} /*\n\t\tNextTo key: 1\n\t\tNextTo value: \"b\"\n\t\tNextTo key: 0\n\t\tNextTo value: \"a\"\n\t*/\n}\n"
  },
  {
    "path": "examples/linkedhashmap/linkedhashmap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/maps/linkedhashmap\"\n\n// LinkedHashMapExample to demonstrate basic usage of LinkedHashMapExample\nfunc main() {\n\tm := linkedhashmap.New[int, string]() // empty (keys are of type int)\n\tm.Put(2, \"b\")                         // 2->b\n\tm.Put(1, \"x\")                         // 2->b, 1->x (insertion-order)\n\tm.Put(1, \"a\")                         // 2->b, 1->a (insertion-order)\n\t_, _ = m.Get(2)                       // b, true\n\t_, _ = m.Get(3)                       // nil, false\n\t_ = m.Values()                        // []interface {}{\"b\", \"a\"} (insertion-order)\n\t_ = m.Keys()                          // []interface {}{2, 1} (insertion-order)\n\tm.Remove(1)                           // 2->b\n\tm.Clear()                             // empty\n\tm.Empty()                             // true\n\tm.Size()                              // 0\n}\n"
  },
  {
    "path": "examples/linkedhashset/linkedhashset.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/sets/linkedhashset\"\n\n// LinkedHashSetExample to demonstrate basic usage of LinkedHashSet\nfunc main() {\n\tset := linkedhashset.New[int]() // empty\n\tset.Add(5)                      // 5\n\tset.Add(4, 4, 3, 2, 1)          // 5, 4, 3, 2, 1 (in insertion-order, duplicates ignored)\n\tset.Remove(4)                   // 5, 3, 2, 1 (in insertion-order)\n\tset.Remove(2, 3)                // 5, 1 (in insertion-order)\n\tset.Contains(1)                 // true\n\tset.Contains(1, 5)              // true\n\tset.Contains(1, 6)              // false\n\t_ = set.Values()                // []int{5, 1} (in insertion-order)\n\tset.Clear()                     // empty\n\tset.Empty()                     // true\n\tset.Size()                      // 0\n}\n"
  },
  {
    "path": "examples/linkedlistqueue/linkedlistqueue.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport llq \"github.com/emirpasic/gods/v2/queues/linkedlistqueue\"\n\n// LinkedListQueueExample to demonstrate basic usage of LinkedListQueue\nfunc main() {\n\tqueue := llq.New[int]() // empty\n\tqueue.Enqueue(1)        // 1\n\tqueue.Enqueue(2)        // 1, 2\n\t_ = queue.Values()      // 1, 2 (FIFO order)\n\t_, _ = queue.Peek()     // 1,true\n\t_, _ = queue.Dequeue()  // 1, true\n\t_, _ = queue.Dequeue()  // 2, true\n\t_, _ = queue.Dequeue()  // nil, false (nothing to deque)\n\tqueue.Enqueue(1)        // 1\n\tqueue.Clear()           // empty\n\tqueue.Empty()           // true\n\t_ = queue.Size()        // 0\n}\n"
  },
  {
    "path": "examples/linkedliststack/linkedliststack.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport lls \"github.com/emirpasic/gods/v2/stacks/linkedliststack\"\n\n// LinkedListStackExample to demonstrate basic usage of LinkedListStack\nfunc main() {\n\tstack := lls.New[int]() // empty\n\tstack.Push(1)           // 1\n\tstack.Push(2)           // 1, 2\n\tstack.Values()          // 2, 1 (LIFO order)\n\t_, _ = stack.Peek()     // 2,true\n\t_, _ = stack.Pop()      // 2, true\n\t_, _ = stack.Pop()      // 1, true\n\t_, _ = stack.Pop()      // nil, false (nothing to pop)\n\tstack.Push(1)           // 1\n\tstack.Clear()           // empty\n\tstack.Empty()           // true\n\tstack.Size()            // 0\n}\n"
  },
  {
    "path": "examples/priorityqueue/priorityqueue.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"cmp\"\n\n\tpq \"github.com/emirpasic/gods/v2/queues/priorityqueue\"\n)\n\n// Element is an entry in the priority queue\ntype Element struct {\n\tname     string\n\tpriority int\n}\n\n// Comparator function (sort by element's priority value in descending order)\nfunc byPriority(a, b Element) int {\n\treturn -cmp.Compare(a.priority, b.priority) // \"-\" descending order\n}\n\n// PriorityQueueExample to demonstrate basic usage of BinaryHeap\nfunc main() {\n\ta := Element{name: \"a\", priority: 1}\n\tb := Element{name: \"b\", priority: 2}\n\tc := Element{name: \"c\", priority: 3}\n\n\tqueue := pq.NewWith(byPriority) // empty\n\tqueue.Enqueue(a)                // {a 1}\n\tqueue.Enqueue(c)                // {c 3}, {a 1}\n\tqueue.Enqueue(b)                // {c 3}, {b 2}, {a 1}\n\t_ = queue.Values()              // [{c 3} {b 2} {a 1}]\n\t_, _ = queue.Peek()             // {c 3} true\n\t_, _ = queue.Dequeue()          // {c 3} true\n\t_, _ = queue.Dequeue()          // {b 2} true\n\t_, _ = queue.Dequeue()          // {a 1} true\n\t_, _ = queue.Dequeue()          // <nil> false (nothing to dequeue)\n\tqueue.Clear()                   // empty\n\t_ = queue.Empty()               // true\n\t_ = queue.Size()                // 0\n}\n"
  },
  {
    "path": "examples/redblacktree/redblacktree.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"fmt\"\n\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// RedBlackTreeExample to demonstrate basic usage of RedBlackTree\nfunc main() {\n\ttree := rbt.New[int, string]() // empty(keys are of type int)\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\n\tfmt.Println(tree)\n\t//\n\t//  RedBlackTree\n\t//  │           ┌── 6\n\t//  │       ┌── 5\n\t//  │   ┌── 4\n\t//  │   │   └── 3\n\t//  └── 2\n\t//       └── 1\n\n\t_ = tree.Values() // []interface {}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"} (in order)\n\t_ = tree.Keys()   // []interface {}{1, 2, 3, 4, 5, 6} (in order)\n\n\ttree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order)\n\tfmt.Println(tree)\n\t//\n\t//  RedBlackTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      │   ┌── 3\n\t//      └── 1\n\n\ttree.Clear() // empty\n\ttree.Empty() // true\n\ttree.Size()  // 0\n}\n"
  },
  {
    "path": "examples/redblacktreeextended/redblacktreeextended.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage redblacktreeextended\n\nimport (\n\t\"fmt\"\n\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// RedBlackTreeExtended to demonstrate how to extend a RedBlackTree to include new functions\ntype RedBlackTreeExtended[K comparable, V any] struct {\n\t*rbt.Tree[K, V]\n}\n\n// GetMin gets the min value and flag if found\nfunc (tree *RedBlackTreeExtended[K, V]) GetMin() (value V, found bool) {\n\tnode, found := tree.getMinFromNode(tree.Root)\n\tif found {\n\t\treturn node.Value, found\n\t}\n\treturn value, false\n}\n\n// GetMax gets the max value and flag if found\nfunc (tree *RedBlackTreeExtended[K, V]) GetMax() (value V, found bool) {\n\tnode, found := tree.getMaxFromNode(tree.Root)\n\tif found {\n\t\treturn node.Value, found\n\t}\n\treturn value, false\n}\n\n// RemoveMin removes the min value and flag if found\nfunc (tree *RedBlackTreeExtended[K, V]) RemoveMin() (value V, deleted bool) {\n\tnode, found := tree.getMinFromNode(tree.Root)\n\tif found {\n\t\ttree.Remove(node.Key)\n\t\treturn node.Value, found\n\t}\n\treturn value, false\n}\n\n// RemoveMax removes the max value and flag if found\nfunc (tree *RedBlackTreeExtended[K, V]) RemoveMax() (value V, deleted bool) {\n\tnode, found := tree.getMaxFromNode(tree.Root)\n\tif found {\n\t\ttree.Remove(node.Key)\n\t\treturn node.Value, found\n\t}\n\treturn value, false\n}\n\nfunc (tree *RedBlackTreeExtended[K, V]) getMinFromNode(node *rbt.Node[K, V]) (foundNode *rbt.Node[K, V], found bool) {\n\tif node == nil {\n\t\treturn nil, false\n\t}\n\tif node.Left == nil {\n\t\treturn node, true\n\t}\n\treturn tree.getMinFromNode(node.Left)\n}\n\nfunc (tree *RedBlackTreeExtended[K, V]) getMaxFromNode(node *rbt.Node[K, V]) (foundNode *rbt.Node[K, V], found bool) {\n\tif node == nil {\n\t\treturn nil, false\n\t}\n\tif node.Right == nil {\n\t\treturn node, true\n\t}\n\treturn tree.getMaxFromNode(node.Right)\n}\n\nfunc print(tree *RedBlackTreeExtended[int, string]) {\n\tmax, _ := tree.GetMax()\n\tmin, _ := tree.GetMin()\n\tfmt.Printf(\"Value for max key: %v \\n\", max)\n\tfmt.Printf(\"Value for min key: %v \\n\", min)\n\tfmt.Println(tree)\n}\n\n// RedBlackTreeExtendedExample main method on how to use the custom red-black tree above\nfunc main() {\n\ttree := RedBlackTreeExtended[int, string]{rbt.New[int, string]()}\n\n\ttree.Put(1, \"a\") // 1->x (in order)\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(3, \"c\") // 1->x, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->x, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->x, 2->b, 3->c, 4->d, 5->e (in order)\n\n\tprint(&tree)\n\t// Value for max key: e\n\t// Value for min key: a\n\t// RedBlackTree\n\t// │       ┌── 5\n\t// │   ┌── 4\n\t// │   │   └── 3\n\t// └── 2\n\t//     └── 1\n\n\ttree.RemoveMin() // 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.RemoveMax() // 2->b, 3->c, 4->d (in order)\n\ttree.RemoveMin() // 3->c, 4->d (in order)\n\ttree.RemoveMax() // 3->c (in order)\n\n\tprint(&tree)\n\t// Value for max key: c\n\t// Value for min key: c\n\t// RedBlackTree\n\t// └── 3\n}\n"
  },
  {
    "path": "examples/serialization/serialization.go",
    "content": "package serialization\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/lists/arraylist\"\n\t\"github.com/emirpasic/gods/v2/maps/hashmap\"\n)\n\n// ListSerializationExample demonstrates how to serialize and deserialize lists to and from JSON\nfunc ListSerializationExample() {\n\tlist := arraylist.New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\n\t// Serialization (marshalling)\n\tjson, err := list.ToJSON()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(string(json)) // [\"a\",\"b\",\"c\"]\n\n\t// Deserialization (unmarshalling)\n\tjson = []byte(`[\"a\",\"b\"]`)\n\terr = list.FromJSON(json)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(list) // ArrayList [\"a\",\"b\"]\n}\n\n// MapSerializationExample demonstrates how to serialize and deserialize maps to and from JSON\nfunc MapSerializationExample() {\n\tm := hashmap.New[string, string]()\n\tm.Put(\"a\", \"1\")\n\tm.Put(\"b\", \"2\")\n\tm.Put(\"c\", \"3\")\n\n\t// Serialization (marshalling)\n\tjson, err := m.ToJSON()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(string(json)) // {\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}\n\n\t// Deserialization (unmarshalling)\n\tjson = []byte(`{\"a\":\"1\",\"b\":\"2\"}`)\n\terr = m.FromJSON(json)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(m) // HashMap {\"a\":\"1\",\"b\":\"2\"}\n}\n"
  },
  {
    "path": "examples/singlylinkedlist/singlylinkedlist.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"cmp\"\n\n\tsll \"github.com/emirpasic/gods/v2/lists/singlylinkedlist\"\n)\n\n// SinglyLinkedListExample to demonstrate basic usage of SinglyLinkedList\nfunc main() {\n\tlist := sll.New[string]()\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Append(\"b\")                      // [\"a\",\"b\"] (same as Add())\n\tlist.Prepend(\"c\")                     // [\"c\",\"a\",\"b\"]\n\tlist.Sort(cmp.Compare[string])        // [\"a\",\"b\",\"c\"]\n\t_, _ = list.Get(0)                    // \"a\",true\n\t_, _ = list.Get(100)                  // nil,false\n\t_ = list.Contains(\"a\", \"b\", \"c\")      // true\n\t_ = list.Contains(\"a\", \"b\", \"c\", \"d\") // false\n\tlist.Remove(2)                        // [\"a\",\"b\"]\n\tlist.Remove(1)                        // [\"a\"]\n\tlist.Remove(0)                        // []\n\tlist.Remove(0)                        // [] (ignored)\n\t_ = list.Empty()                      // true\n\t_ = list.Size()                       // 0\n\tlist.Add(\"a\")                         // [\"a\"]\n\tlist.Clear()                          // []\n}\n"
  },
  {
    "path": "examples/treebidimap/treebidimap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport (\n\t\"github.com/emirpasic/gods/v2/maps/treebidimap\"\n)\n\n// TreeBidiMapExample to demonstrate basic usage of TreeBidiMap\nfunc main() {\n\tm := treebidimap.New[int, string]()\n\tm.Put(1, \"x\")        // 1->x\n\tm.Put(3, \"b\")        // 1->x, 3->b (ordered)\n\tm.Put(1, \"a\")        // 1->a, 3->b (ordered)\n\tm.Put(2, \"b\")        // 1->a, 2->b (ordered)\n\t_, _ = m.GetKey(\"a\") // 1, true\n\t_, _ = m.Get(2)      // b, true\n\t_, _ = m.Get(3)      // nil, false\n\t_ = m.Values()       // []interface {}{\"a\", \"b\"} (ordered)\n\t_ = m.Keys()         // []interface {}{1, 2} (ordered)\n\tm.Remove(1)          // 2->b\n\tm.Clear()            // empty\n\tm.Empty()            // true\n\tm.Size()             // 0\n}\n"
  },
  {
    "path": "examples/treemap/treemap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/maps/treemap\"\n\n// TreeMapExample to demonstrate basic usage of TreeMap\nfunc main() {\n\tm := treemap.New[int, string]() // empty\n\tm.Put(1, \"x\")                   // 1->x\n\tm.Put(2, \"b\")                   // 1->x, 2->b (in order)\n\tm.Put(1, \"a\")                   // 1->a, 2->b (in order)\n\t_, _ = m.Get(2)                 // b, true\n\t_, _ = m.Get(3)                 // nil, false\n\t_ = m.Values()                  // []interface {}{\"a\", \"b\"} (in order)\n\t_ = m.Keys()                    // []interface {}{1, 2} (in order)\n\tm.Remove(1)                     // 2->b\n\tm.Clear()                       // empty\n\tm.Empty()                       // true\n\tm.Size()                        // 0\n}\n"
  },
  {
    "path": "examples/treeset/treeset.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage main\n\nimport \"github.com/emirpasic/gods/v2/sets/treeset\"\n\n// TreeSetExample to demonstrate basic usage of TreeSet\nfunc main() {\n\tset := treeset.New[int]() // empty\n\tset.Add(1)                // 1\n\tset.Add(2, 2, 3, 4, 5)    // 1, 2, 3, 4, 5 (in order, duplicates ignored)\n\tset.Remove(4)             // 1, 2, 3, 5 (in order)\n\tset.Remove(2, 3)          // 1, 5 (in order)\n\tset.Contains(1)           // true\n\tset.Contains(1, 5)        // true\n\tset.Contains(1, 6)        // false\n\t_ = set.Values()          // []int{1,5} (in order)\n\tset.Clear()               // empty\n\tset.Empty()               // true\n\tset.Size()                // 0\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/emirpasic/gods/v2\n\ngo 1.21\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=\ngithub.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=\n"
  },
  {
    "path": "lists/arraylist/arraylist.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package arraylist implements the array list.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29\npackage arraylist\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert List implementation\nvar _ lists.List[int] = (*List[int])(nil)\n\n// List holds the elements in a slice\ntype List[T comparable] struct {\n\telements []T\n}\n\nconst (\n\tgrowthFactor = float32(2.0)  // growth by 100%\n\tshrinkFactor = float32(0.25) // shrink when size is 25% of capacity (0 means never shrink)\n)\n\n// New instantiates a new list and adds the passed values, if any, to the list\nfunc New[T comparable](values ...T) *List[T] {\n\tlist := &List[T]{}\n\tif len(values) > 0 {\n\t\tlist.Add(values...)\n\t}\n\treturn list\n}\n\n// Add appends a value at the end of the list\nfunc (list *List[T]) Add(values ...T) {\n\tl := len(list.elements)\n\tlist.growBy(len(values))\n\tfor i := range values {\n\t\tlist.elements[l+i] = values[i]\n\t}\n}\n\n// Get returns the element at index.\n// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.\nfunc (list *List[T]) Get(index int) (T, bool) {\n\n\tif !list.withinRange(index) {\n\t\tvar t T\n\t\treturn t, false\n\t}\n\n\treturn list.elements[index], true\n}\n\n// Remove removes the element at the given index from the list.\nfunc (list *List[T]) Remove(index int) {\n\n\tif !list.withinRange(index) {\n\t\treturn\n\t}\n\n\tlist.elements = slices.Delete(list.elements, index, index+1)\n\tlist.shrink()\n}\n\n// Contains checks if elements (one or more) are present in the set.\n// All elements have to be present in the set for the method to return true.\n// Performance time complexity of n^2.\n// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.\nfunc (list *List[T]) Contains(values ...T) bool {\n\tfor _, searchValue := range values {\n\t\tif !slices.Contains(list.elements, searchValue) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Values returns all elements in the list.\nfunc (list *List[T]) Values() []T {\n\treturn slices.Clone(list.elements)\n}\n\n// IndexOf returns index of provided element\nfunc (list *List[T]) IndexOf(value T) int {\n\treturn slices.Index(list.elements, value)\n}\n\n// Empty returns true if list does not contain any elements.\nfunc (list *List[T]) Empty() bool {\n\treturn len(list.elements) == 0\n}\n\n// Size returns number of elements within the list.\nfunc (list *List[T]) Size() int {\n\treturn len(list.elements)\n}\n\n// Clear removes all elements from the list.\nfunc (list *List[T]) Clear() {\n\tclear(list.elements[:cap(list.elements)])\n\tlist.elements = list.elements[:0]\n}\n\n// Sort sorts values (in-place) using.\nfunc (list *List[T]) Sort(comparator utils.Comparator[T]) {\n\tif len(list.elements) < 2 {\n\t\treturn\n\t}\n\tslices.SortFunc(list.elements, comparator)\n}\n\n// Swap swaps the two values at the specified positions.\nfunc (list *List[T]) Swap(i, j int) {\n\tif list.withinRange(i) && list.withinRange(j) {\n\t\tlist.elements[i], list.elements[j] = list.elements[j], list.elements[i]\n\t}\n}\n\n// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.\n// Does not do anything if position is negative or bigger than list's size\n// Note: position equal to list's size is valid, i.e. append.\nfunc (list *List[T]) Insert(index int, values ...T) {\n\tif !list.withinRange(index) {\n\t\t// Append\n\t\tif index == len(list.elements) {\n\t\t\tlist.Add(values...)\n\t\t}\n\t\treturn\n\t}\n\n\tl := len(list.elements)\n\tlist.growBy(len(values))\n\tlist.elements = slices.Insert(list.elements[:l], index, values...)\n}\n\n// Set the value at specified index\n// Does not do anything if position is negative or bigger than list's size\n// Note: position equal to list's size is valid, i.e. append.\nfunc (list *List[T]) Set(index int, value T) {\n\n\tif !list.withinRange(index) {\n\t\t// Append\n\t\tif index == len(list.elements) {\n\t\t\tlist.Add(value)\n\t\t}\n\t\treturn\n\t}\n\n\tlist.elements[index] = value\n}\n\n// String returns a string representation of container\nfunc (list *List[T]) String() string {\n\tstr := \"ArrayList\\n\"\n\tvalues := make([]string, 0, len(list.elements))\n\tfor _, value := range list.elements {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (list *List[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < len(list.elements)\n}\n\nfunc (list *List[T]) resize(len, cap int) {\n\tnewElements := make([]T, len, cap)\n\tcopy(newElements, list.elements)\n\tlist.elements = newElements\n}\n\n// Expand the array if necessary, i.e. capacity will be reached if we add n elements\nfunc (list *List[T]) growBy(n int) {\n\t// When capacity is reached, grow by a factor of growthFactor and add number of elements\n\tcurrentCapacity := cap(list.elements)\n\n\tif newLength := len(list.elements) + n; newLength >= currentCapacity {\n\t\tnewCapacity := int(growthFactor * float32(currentCapacity+n))\n\t\tlist.resize(newLength, newCapacity)\n\t} else {\n\t\tlist.elements = list.elements[:newLength]\n\t}\n}\n\n// Shrink the array if necessary, i.e. when size is shrinkFactor percent of current capacity\nfunc (list *List[T]) shrink() {\n\tif shrinkFactor == 0.0 {\n\t\treturn\n\t}\n\t// Shrink when size is at shrinkFactor * capacity\n\tcurrentCapacity := cap(list.elements)\n\tif len(list.elements) <= int(float32(currentCapacity)*shrinkFactor) {\n\t\tlist.resize(len(list.elements), len(list.elements))\n\t}\n}\n"
  },
  {
    "path": "lists/arraylist/arraylist_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraylist\n\nimport (\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestListNew(t *testing.T) {\n\tlist1 := New[int]()\n\n\tif actualValue := list1.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\tlist2 := New[int](1, 2)\n\n\tif actualValue := list2.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\n\tif actualValue, ok := list2.Get(0); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\n\tif actualValue, ok := list2.Get(1); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\n\tif actualValue, ok := list2.Get(2); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListAdd(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue := list.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListIndexOf(t *testing.T) {\n\tlist := New[string]()\n\n\texpectedIndex := -1\n\tif index := list.IndexOf(\"a\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\n\texpectedIndex = 0\n\tif index := list.IndexOf(\"a\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n\n\texpectedIndex = 1\n\tif index := list.IndexOf(\"b\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n\n\texpectedIndex = 2\n\tif index := list.IndexOf(\"c\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n}\n\nfunc TestListRemove(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tlist.Remove(2)\n\tif actualValue, ok := list.Get(2); actualValue != \"\" || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"\")\n\t}\n\tlist.Remove(1)\n\tlist.Remove(0)\n\tlist.Remove(0) // no effect\n\tif actualValue := list.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListGet(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue, ok := list.Get(0); actualValue != \"a\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"a\")\n\t}\n\tif actualValue, ok := list.Get(1); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(3); actualValue != \"\" || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"\")\n\t}\n\tlist.Remove(0)\n\tif actualValue, ok := list.Get(0); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n}\n\nfunc TestListSwap(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tlist.Swap(0, 1)\n\tif actualValue, ok := list.Get(0); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n}\n\nfunc TestListSort(t *testing.T) {\n\tlist := New[string]()\n\tlist.Sort(cmp.Compare[string])\n\tlist.Add(\"e\", \"f\", \"g\", \"a\", \"b\", \"c\", \"d\")\n\tlist.Sort(cmp.Compare[string])\n\tfor i := 1; i < list.Size(); i++ {\n\t\ta, _ := list.Get(i - 1)\n\t\tb, _ := list.Get(i)\n\t\tif a > b {\n\t\t\tt.Errorf(\"Not sorted! %s > %s\", a, b)\n\t\t}\n\t}\n}\n\nfunc TestListClear(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"e\", \"f\", \"g\", \"a\", \"b\", \"c\", \"d\")\n\tlist.Clear()\n\tif actualValue := list.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListContains(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue := list.Contains(\"a\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Contains(\"\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\", \"d\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tlist.Clear()\n\tif actualValue := list.Contains(\"a\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n}\n\nfunc TestListValues(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListInsert(t *testing.T) {\n\tlist := New[string]()\n\tlist.Insert(0, \"b\", \"c\")\n\tlist.Insert(0, \"a\")\n\tlist.Insert(10, \"x\") // ignore\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tlist.Insert(3, \"d\") // append\n\tif actualValue := list.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\tif actualValue, expectedValue := strings.Join(list.Values(), \"\"), \"abcd\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListSet(t *testing.T) {\n\tlist := New[string]()\n\tlist.Set(0, \"a\")\n\tlist.Set(1, \"b\")\n\tif actualValue := list.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tlist.Set(2, \"c\") // append\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tlist.Set(4, \"d\")  // ignore\n\tlist.Set(1, \"bb\") // update\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"bb\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListEach(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tlist.Each(func(index int, value string) {\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestListMap(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tmappedList := list.Map(func(index int, value string) string {\n\t\treturn \"mapped: \" + value\n\t})\n\tif actualValue, _ := mappedList.Get(0); actualValue != \"mapped: a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: a\")\n\t}\n\tif actualValue, _ := mappedList.Get(1); actualValue != \"mapped: b\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: b\")\n\t}\n\tif actualValue, _ := mappedList.Get(2); actualValue != \"mapped: c\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: c\")\n\t}\n\tif mappedList.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedList.Size(), 3)\n\t}\n}\n\nfunc TestListSelect(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tselectedList := list.Select(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif actualValue, _ := selectedList.Get(0); actualValue != \"a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: a\")\n\t}\n\tif actualValue, _ := selectedList.Get(1); actualValue != \"b\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: b\")\n\t}\n\tif selectedList.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedList.Size(), 3)\n\t}\n}\n\nfunc TestListAny(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tany := list.Any(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = list.Any(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\nfunc TestListAll(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tall := list.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = list.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\nfunc TestListFind(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tfoundIndex, foundValue := list.Find(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif foundValue != \"c\" || foundIndex != 2 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, \"c\", 2)\n\t}\n\tfoundIndex, foundValue = list.Find(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif foundValue != \"\" || foundIndex != -1 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, nil, nil)\n\t}\n}\nfunc TestListChaining(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tchainedList := list.Select(func(index int, value string) bool {\n\t\treturn value > \"a\"\n\t}).Map(func(index int, value string) string {\n\t\treturn value + value\n\t})\n\tif chainedList.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", chainedList.Size(), 2)\n\t}\n\tif actualValue, ok := chainedList.Get(0); actualValue != \"bb\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n\tif actualValue, ok := chainedList.Get(1); actualValue != \"cc\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListIteratorNextOnEmpty(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t}\n}\n\nfunc TestListIteratorNext(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit := list.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListIteratorPrevOnEmpty(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t}\n}\n\nfunc TestListIteratorPrev(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit := list.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListIteratorBegin(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tit.Begin()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestListIteratorEnd(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit.End()\n\tif index := it.Index(); index != list.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, list.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != list.Size()-1 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, list.Size()-1, \"c\")\n\t}\n}\n\nfunc TestListIteratorFirst(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tlist.Add(\"a\", \"b\", \"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestListIteratorLast(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tlist.Add(\"a\", \"b\", \"c\")\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"c\")\n\t}\n}\n\nfunc TestListIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tlist := New[string]()\n\t\tit := list.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"xx\", \"yy\")\n\t\tit := list.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := list.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestListIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tlist := New[string]()\n\t\tit := list.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"xx\", \"yy\")\n\t\tit := list.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := list.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestListSerialization(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := list.ToJSON()\n\tassert()\n\n\terr = list.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]any{\"a\", \"b\", \"c\", list})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &list)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestListString(t *testing.T) {\n\tc := New[int]()\n\tc.Add(1)\n\tif !strings.HasPrefix(c.String(), \"ArrayList\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkAdd(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Add(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkArrayListGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkArrayListGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkArrayListGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkArrayListGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkArrayListAdd100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkArrayListAdd1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkArrayListAdd10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkArrayListAdd100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkArrayListRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkArrayListRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkArrayListRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkArrayListRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n"
  },
  {
    "path": "lists/arraylist/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraylist\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithIndex[int] = (*List[int])(nil)\n\n// Each calls the given function once for each element, passing that element's index and value.\nfunc (list *List[T]) Each(f func(index int, value T)) {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Index(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a\n// container containing the values returned by the given function.\nfunc (list *List[T]) Map(f func(index int, value T) T) *List[T] {\n\tnewList := &List[T]{}\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tnewList.Add(f(iterator.Index(), iterator.Value()))\n\t}\n\treturn newList\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (list *List[T]) Select(f func(index int, value T) bool) *List[T] {\n\tnewList := &List[T]{}\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\tnewList.Add(iterator.Value())\n\t\t}\n\t}\n\treturn newList\n}\n\n// Any passes each element of the collection to the given function and\n// returns true if the function ever returns true for any element.\nfunc (list *List[T]) Any(f func(index int, value T) bool) bool {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the collection to the given function and\n// returns true if the function returns true for all elements.\nfunc (list *List[T]) All(f func(index int, value T) bool) bool {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Index(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (index,value) for which the function is true or -1,nil otherwise\n// if no element matches the criteria.\nfunc (list *List[T]) Find(f func(index int, value T) bool) (int, T) {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn iterator.Index(), iterator.Value()\n\t\t}\n\t}\n\tvar t T\n\treturn -1, t\n}\n"
  },
  {
    "path": "lists/arraylist/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraylist\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[T comparable] struct {\n\tlist  *List[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (list *List[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{list: list, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.list.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.list.withinRange(iterator.index)\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\treturn iterator.list.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\treturn iterator.list.elements[iterator.index]\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.list.Size()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "lists/arraylist/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraylist\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*List[int])(nil)\nvar _ containers.JSONDeserializer = (*List[int])(nil)\n\n// ToJSON outputs the JSON representation of list's elements.\nfunc (list *List[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(list.elements)\n}\n\n// FromJSON populates list's elements from the input JSON representation.\nfunc (list *List[T]) FromJSON(data []byte) error {\n\terr := json.Unmarshal(data, &list.elements)\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (list *List[T]) UnmarshalJSON(bytes []byte) error {\n\treturn list.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (list *List[T]) MarshalJSON() ([]byte, error) {\n\treturn list.ToJSON()\n}\n"
  },
  {
    "path": "lists/doublylinkedlist/doublylinkedlist.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package doublylinkedlist implements the doubly-linked list.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29\npackage doublylinkedlist\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert List implementation\nvar _ lists.List[any] = (*List[any])(nil)\n\n// List holds the elements, where each element points to the next and previous element\ntype List[T comparable] struct {\n\tfirst *element[T]\n\tlast  *element[T]\n\tsize  int\n}\n\ntype element[T comparable] struct {\n\tvalue T\n\tprev  *element[T]\n\tnext  *element[T]\n}\n\n// New instantiates a new list and adds the passed values, if any, to the list\nfunc New[T comparable](values ...T) *List[T] {\n\tlist := &List[T]{}\n\tif len(values) > 0 {\n\t\tlist.Add(values...)\n\t}\n\treturn list\n}\n\n// Add appends a value (one or more) at the end of the list (same as Append())\nfunc (list *List[T]) Add(values ...T) {\n\tfor _, value := range values {\n\t\tnewElement := &element[T]{value: value, prev: list.last}\n\t\tif list.size == 0 {\n\t\t\tlist.first = newElement\n\t\t\tlist.last = newElement\n\t\t} else {\n\t\t\tlist.last.next = newElement\n\t\t\tlist.last = newElement\n\t\t}\n\t\tlist.size++\n\t}\n}\n\n// Append appends a value (one or more) at the end of the list (same as Add())\nfunc (list *List[T]) Append(values ...T) {\n\tlist.Add(values...)\n}\n\n// Prepend prepends a values (or more)\nfunc (list *List[T]) Prepend(values ...T) {\n\t// in reverse to keep passed order i.e. [\"c\",\"d\"] -> Prepend([\"a\",\"b\"]) -> [\"a\",\"b\",\"c\",d\"]\n\tfor v := len(values) - 1; v >= 0; v-- {\n\t\tnewElement := &element[T]{value: values[v], next: list.first}\n\t\tif list.size == 0 {\n\t\t\tlist.first = newElement\n\t\t\tlist.last = newElement\n\t\t} else {\n\t\t\tlist.first.prev = newElement\n\t\t\tlist.first = newElement\n\t\t}\n\t\tlist.size++\n\t}\n}\n\n// Get returns the element at index.\n// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.\nfunc (list *List[T]) Get(index int) (T, bool) {\n\n\tif !list.withinRange(index) {\n\t\tvar t T\n\t\treturn t, false\n\t}\n\n\t// determine traversal direction, last to first or first to last\n\tif list.size-index < index {\n\t\telement := list.last\n\t\tfor e := list.size - 1; e != index; e, element = e-1, element.prev {\n\t\t}\n\t\treturn element.value, true\n\t}\n\telement := list.first\n\tfor e := 0; e != index; e, element = e+1, element.next {\n\t}\n\treturn element.value, true\n}\n\n// Remove removes the element at the given index from the list.\nfunc (list *List[T]) Remove(index int) {\n\n\tif !list.withinRange(index) {\n\t\treturn\n\t}\n\n\tif list.size == 1 {\n\t\tlist.Clear()\n\t\treturn\n\t}\n\n\tvar element *element[T]\n\t// determine traversal direction, last to first or first to last\n\tif list.size-index < index {\n\t\telement = list.last\n\t\tfor e := list.size - 1; e != index; e, element = e-1, element.prev {\n\t\t}\n\t} else {\n\t\telement = list.first\n\t\tfor e := 0; e != index; e, element = e+1, element.next {\n\t\t}\n\t}\n\n\tif element == list.first {\n\t\tlist.first = element.next\n\t}\n\tif element == list.last {\n\t\tlist.last = element.prev\n\t}\n\tif element.prev != nil {\n\t\telement.prev.next = element.next\n\t}\n\tif element.next != nil {\n\t\telement.next.prev = element.prev\n\t}\n\n\telement = nil\n\n\tlist.size--\n}\n\n// Contains check if values (one or more) are present in the set.\n// All values have to be present in the set for the method to return true.\n// Performance time complexity of n^2.\n// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.\nfunc (list *List[T]) Contains(values ...T) bool {\n\n\tif len(values) == 0 {\n\t\treturn true\n\t}\n\tif list.size == 0 {\n\t\treturn false\n\t}\n\tfor _, value := range values {\n\t\tfound := false\n\t\tfor element := list.first; element != nil; element = element.next {\n\t\t\tif element.value == value {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Values returns all elements in the list.\nfunc (list *List[T]) Values() []T {\n\tvalues := make([]T, list.size, list.size)\n\tfor e, element := 0, list.first; element != nil; e, element = e+1, element.next {\n\t\tvalues[e] = element.value\n\t}\n\treturn values\n}\n\n// IndexOf returns index of provided element\nfunc (list *List[T]) IndexOf(value T) int {\n\tif list.size == 0 {\n\t\treturn -1\n\t}\n\tfor index, element := range list.Values() {\n\t\tif element == value {\n\t\t\treturn index\n\t\t}\n\t}\n\treturn -1\n}\n\n// Empty returns true if list does not contain any elements.\nfunc (list *List[T]) Empty() bool {\n\treturn list.size == 0\n}\n\n// Size returns number of elements within the list.\nfunc (list *List[T]) Size() int {\n\treturn list.size\n}\n\n// Clear removes all elements from the list.\nfunc (list *List[T]) Clear() {\n\tlist.size = 0\n\tlist.first = nil\n\tlist.last = nil\n}\n\n// Sort sorts values (in-place) using a Comparator.\nfunc (list *List[T]) Sort(comparator utils.Comparator[T]) {\n\n\tif list.size < 2 {\n\t\treturn\n\t}\n\n\tvalues := list.Values()\n\tslices.SortFunc(values, comparator)\n\n\tlist.Clear()\n\n\tlist.Add(values...)\n\n}\n\n// Swap swaps values of two elements at the given indices.\nfunc (list *List[T]) Swap(i, j int) {\n\tif list.withinRange(i) && list.withinRange(j) && i != j {\n\t\tvar element1, element2 *element[T]\n\t\tfor e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next {\n\t\t\tswitch e {\n\t\t\tcase i:\n\t\t\t\telement1 = currentElement\n\t\t\tcase j:\n\t\t\t\telement2 = currentElement\n\t\t\t}\n\t\t}\n\t\telement1.value, element2.value = element2.value, element1.value\n\t}\n}\n\n// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.\n// Does not do anything if position is negative or bigger than list's size\n// Note: position equal to list's size is valid, i.e. append.\nfunc (list *List[T]) Insert(index int, values ...T) {\n\n\tif !list.withinRange(index) {\n\t\t// Append\n\t\tif index == list.size {\n\t\t\tlist.Add(values...)\n\t\t}\n\t\treturn\n\t}\n\n\tvar beforeElement *element[T]\n\tvar foundElement *element[T]\n\t// determine traversal direction, last to first or first to last\n\tif list.size-index < index {\n\t\tfoundElement = list.last\n\t\tbeforeElement = list.last.prev\n\t\tfor e := list.size - 1; e != index; e, foundElement = e-1, foundElement.prev {\n\t\t\tbeforeElement = beforeElement.prev\n\t\t}\n\t} else {\n\t\tfoundElement = list.first\n\t\tfor e := 0; e != index; e, foundElement = e+1, foundElement.next {\n\t\t\tbeforeElement = foundElement\n\t\t}\n\t}\n\n\tif foundElement == list.first {\n\t\toldNextElement := list.first\n\t\tfor i, value := range values {\n\t\t\tnewElement := &element[T]{value: value}\n\t\t\tif i == 0 {\n\t\t\t\tlist.first = newElement\n\t\t\t} else {\n\t\t\t\tnewElement.prev = beforeElement\n\t\t\t\tbeforeElement.next = newElement\n\t\t\t}\n\t\t\tbeforeElement = newElement\n\t\t}\n\t\toldNextElement.prev = beforeElement\n\t\tbeforeElement.next = oldNextElement\n\t} else {\n\t\toldNextElement := beforeElement.next\n\t\tfor _, value := range values {\n\t\t\tnewElement := &element[T]{value: value}\n\t\t\tnewElement.prev = beforeElement\n\t\t\tbeforeElement.next = newElement\n\t\t\tbeforeElement = newElement\n\t\t}\n\t\toldNextElement.prev = beforeElement\n\t\tbeforeElement.next = oldNextElement\n\t}\n\n\tlist.size += len(values)\n}\n\n// Set value at specified index position\n// Does not do anything if position is negative or bigger than list's size\n// Note: position equal to list's size is valid, i.e. append.\nfunc (list *List[T]) Set(index int, value T) {\n\n\tif !list.withinRange(index) {\n\t\t// Append\n\t\tif index == list.size {\n\t\t\tlist.Add(value)\n\t\t}\n\t\treturn\n\t}\n\n\tvar foundElement *element[T]\n\t// determine traversal direction, last to first or first to last\n\tif list.size-index < index {\n\t\tfoundElement = list.last\n\t\tfor e := list.size - 1; e != index; {\n\t\t\tfmt.Println(\"Set last\", index, value, foundElement, foundElement.prev)\n\t\t\te, foundElement = e-1, foundElement.prev\n\t\t}\n\t} else {\n\t\tfoundElement = list.first\n\t\tfor e := 0; e != index; {\n\t\t\te, foundElement = e+1, foundElement.next\n\t\t}\n\t}\n\n\tfoundElement.value = value\n}\n\n// String returns a string representation of container\nfunc (list *List[T]) String() string {\n\tstr := \"DoublyLinkedList\\n\"\n\tvalues := []string{}\n\tfor element := list.first; element != nil; element = element.next {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", element.value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (list *List[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < list.size\n}\n"
  },
  {
    "path": "lists/doublylinkedlist/doublylinkedlist_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage doublylinkedlist\n\nimport (\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestListNew(t *testing.T) {\n\tlist1 := New[int]()\n\n\tif actualValue := list1.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\tlist2 := New[int](1, 2)\n\n\tif actualValue := list2.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\n\tif actualValue, ok := list2.Get(0); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\n\tif actualValue, ok := list2.Get(1); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\n\tif actualValue, ok := list2.Get(2); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListAdd(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue := list.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListAppendAndPrepend(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"b\")\n\tlist.Prepend(\"a\")\n\tlist.Append(\"c\")\n\tif actualValue := list.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := list.Get(0); actualValue != \"a\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(1); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListRemove(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tlist.Remove(2)\n\tif actualValue, ok := list.Get(2); actualValue != \"\" || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"\")\n\t}\n\tlist.Remove(1)\n\tlist.Remove(0)\n\tlist.Remove(0) // no effect\n\tif actualValue := list.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListGet(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue, ok := list.Get(0); actualValue != \"a\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"a\")\n\t}\n\tif actualValue, ok := list.Get(1); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(3); actualValue != \"\" || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"\")\n\t}\n\tlist.Remove(0)\n\tif actualValue, ok := list.Get(0); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n}\n\nfunc TestListSwap(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tlist.Swap(0, 1)\n\tif actualValue, ok := list.Get(0); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n}\n\nfunc TestListSort(t *testing.T) {\n\tlist := New[string]()\n\tlist.Sort(cmp.Compare[string])\n\tlist.Add(\"e\", \"f\", \"g\", \"a\", \"b\", \"c\", \"d\")\n\tlist.Sort(cmp.Compare[string])\n\tfor i := 1; i < list.Size(); i++ {\n\t\ta, _ := list.Get(i - 1)\n\t\tb, _ := list.Get(i)\n\t\tif a > b {\n\t\t\tt.Errorf(\"Not sorted! %s > %s\", a, b)\n\t\t}\n\t}\n}\n\nfunc TestListClear(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"e\", \"f\", \"g\", \"a\", \"b\", \"c\", \"d\")\n\tlist.Clear()\n\tif actualValue := list.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListContains(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue := list.Contains(\"a\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Contains(\"\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\", \"d\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tlist.Clear()\n\tif actualValue := list.Contains(\"a\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n}\n\nfunc TestListValues(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListInsert(t *testing.T) {\n\tlist := New[string]()\n\tlist.Insert(0, \"b\", \"c\", \"d\")\n\tlist.Insert(0, \"a\")\n\tlist.Insert(10, \"x\") // ignore\n\tif actualValue := list.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\tlist.Insert(4, \"g\") // append\n\tif actualValue := list.Size(); actualValue != 5 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 5)\n\t}\n\tif actualValue, expectedValue := strings.Join(list.Values(), \"\"), \"abcdg\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tlist.Insert(4, \"e\", \"f\") // last to first traversal\n\tif actualValue := list.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\tif actualValue, expectedValue := strings.Join(list.Values(), \"\"), \"abcdefg\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListSet(t *testing.T) {\n\tlist := New[string]()\n\tlist.Set(0, \"a\")\n\tlist.Set(1, \"b\")\n\tif actualValue := list.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tlist.Set(2, \"c\") // append\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tlist.Set(4, \"d\")  // ignore\n\tlist.Set(1, \"bb\") // update\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"bb\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListEach(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tlist.Each(func(index int, value string) {\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestListMap(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tmappedList := list.Map(func(index int, value string) string {\n\t\treturn \"mapped: \" + value\n\t})\n\tif actualValue, _ := mappedList.Get(0); actualValue != \"mapped: a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: a\")\n\t}\n\tif actualValue, _ := mappedList.Get(1); actualValue != \"mapped: b\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: b\")\n\t}\n\tif actualValue, _ := mappedList.Get(2); actualValue != \"mapped: c\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: c\")\n\t}\n\tif mappedList.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedList.Size(), 3)\n\t}\n}\n\nfunc TestListSelect(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tselectedList := list.Select(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif actualValue, _ := selectedList.Get(0); actualValue != \"a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: a\")\n\t}\n\tif actualValue, _ := selectedList.Get(1); actualValue != \"b\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: b\")\n\t}\n\tif selectedList.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedList.Size(), 3)\n\t}\n}\n\nfunc TestListAny(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tany := list.Any(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = list.Any(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\nfunc TestListAll(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tall := list.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = list.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\nfunc TestListFind(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tfoundIndex, foundValue := list.Find(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif foundValue != \"c\" || foundIndex != 2 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, \"c\", 2)\n\t}\n\tfoundIndex, foundValue = list.Find(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif foundValue != \"\" || foundIndex != -1 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, nil, nil)\n\t}\n}\nfunc TestListChaining(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tchainedList := list.Select(func(index int, value string) bool {\n\t\treturn value > \"a\"\n\t}).Map(func(index int, value string) string {\n\t\treturn value + value\n\t})\n\tif chainedList.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", chainedList.Size(), 2)\n\t}\n\tif actualValue, ok := chainedList.Get(0); actualValue != \"bb\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n\tif actualValue, ok := chainedList.Get(1); actualValue != \"cc\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListIteratorNextOnEmpty(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t}\n}\n\nfunc TestListIteratorNext(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit := list.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListIteratorPrevOnEmpty(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t}\n}\n\nfunc TestListIteratorPrev(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit := list.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListIteratorBegin(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tit.Begin()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestListIteratorEnd(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit.End()\n\tif index := it.Index(); index != list.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, list.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != list.Size()-1 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, list.Size()-1, \"c\")\n\t}\n}\n\nfunc TestListIteratorFirst(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tlist.Add(\"a\", \"b\", \"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestListIteratorLast(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tlist.Add(\"a\", \"b\", \"c\")\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"c\")\n\t}\n}\n\nfunc TestListIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tlist := New[string]()\n\t\tit := list.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"xx\", \"yy\")\n\t\tit := list.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := list.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestListIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tlist := New[string]()\n\t\tit := list.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"xx\", \"yy\")\n\t\tit := list.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := list.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestListSerialization(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := list.ToJSON()\n\tassert()\n\n\terr = list.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]any{\"a\", \"b\", \"c\", list})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &list)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestListString(t *testing.T) {\n\tc := New[int]()\n\tc.Add(1)\n\tif !strings.HasPrefix(c.String(), \"DoublyLinkedList\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkAdd(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Add(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkDoublyLinkedListGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListAdd100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListAdd1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListAdd10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListAdd100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkDoublyLinkedListRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n"
  },
  {
    "path": "lists/doublylinkedlist/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage doublylinkedlist\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithIndex[int] = (*List[int])(nil)\n\n// Each calls the given function once for each element, passing that element's index and value.\nfunc (list *List[T]) Each(f func(index int, value T)) {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Index(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a\n// container containing the values returned by the given function.\nfunc (list *List[T]) Map(f func(index int, value T) T) *List[T] {\n\tnewList := &List[T]{}\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tnewList.Add(f(iterator.Index(), iterator.Value()))\n\t}\n\treturn newList\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (list *List[T]) Select(f func(index int, value T) bool) *List[T] {\n\tnewList := &List[T]{}\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\tnewList.Add(iterator.Value())\n\t\t}\n\t}\n\treturn newList\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (list *List[T]) Any(f func(index int, value T) bool) bool {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (list *List[T]) All(f func(index int, value T) bool) bool {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Index(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (index,value) for which the function is true or -1,nil otherwise\n// if no element matches the criteria.\nfunc (list *List[T]) Find(f func(index int, value T) bool) (index int, value T) {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn iterator.Index(), iterator.Value()\n\t\t}\n\t}\n\tvar t T\n\treturn -1, t\n}\n"
  },
  {
    "path": "lists/doublylinkedlist/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage doublylinkedlist\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[T comparable] struct {\n\tlist    *List[T]\n\tindex   int\n\telement *element[T]\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (list *List[T]) Iterator() Iterator[T] {\n\treturn Iterator[T]{list: list, index: -1, element: nil}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.list.size {\n\t\titerator.index++\n\t}\n\tif !iterator.list.withinRange(iterator.index) {\n\t\titerator.element = nil\n\t\treturn false\n\t}\n\tif iterator.index != 0 {\n\t\titerator.element = iterator.element.next\n\t} else {\n\t\titerator.element = iterator.list.first\n\t}\n\treturn true\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\tif !iterator.list.withinRange(iterator.index) {\n\t\titerator.element = nil\n\t\treturn false\n\t}\n\tif iterator.index == iterator.list.size-1 {\n\t\titerator.element = iterator.list.last\n\t} else {\n\t\titerator.element = iterator.element.prev\n\t}\n\treturn iterator.list.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\treturn iterator.element.value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n\titerator.element = nil\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.list.size\n\titerator.element = iterator.list.last\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "lists/doublylinkedlist/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage doublylinkedlist\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*List[int])(nil)\nvar _ containers.JSONDeserializer = (*List[int])(nil)\n\n// ToJSON outputs the JSON representation of list's elements.\nfunc (list *List[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(list.Values())\n}\n\n// FromJSON populates list's elements from the input JSON representation.\nfunc (list *List[T]) FromJSON(data []byte) error {\n\tvar elements []T\n\terr := json.Unmarshal(data, &elements)\n\tif err == nil {\n\t\tlist.Clear()\n\t\tlist.Add(elements...)\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (list *List[T]) UnmarshalJSON(bytes []byte) error {\n\treturn list.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (list *List[T]) MarshalJSON() ([]byte, error) {\n\treturn list.ToJSON()\n}\n"
  },
  {
    "path": "lists/lists.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package lists provides an abstract List interface.\n//\n// 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.\n//\n// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29\npackage lists\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// List interface that all lists implement\ntype List[T comparable] interface {\n\tGet(index int) (T, bool)\n\tRemove(index int)\n\tAdd(values ...T)\n\tContains(values ...T) bool\n\tSort(comparator utils.Comparator[T])\n\tSwap(index1, index2 int)\n\tInsert(index int, values ...T)\n\tSet(index int, value T)\n\n\tcontainers.Container[T]\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n"
  },
  {
    "path": "lists/singlylinkedlist/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage singlylinkedlist\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithIndex[int] = (*List[int])(nil)\n\n// Each calls the given function once for each element, passing that element's index and value.\nfunc (list *List[T]) Each(f func(index int, value T)) {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Index(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a\n// container containing the values returned by the given function.\nfunc (list *List[T]) Map(f func(index int, value T) T) *List[T] {\n\tnewList := &List[T]{}\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tnewList.Add(f(iterator.Index(), iterator.Value()))\n\t}\n\treturn newList\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (list *List[T]) Select(f func(index int, value T) bool) *List[T] {\n\tnewList := &List[T]{}\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\tnewList.Add(iterator.Value())\n\t\t}\n\t}\n\treturn newList\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (list *List[T]) Any(f func(index int, value T) bool) bool {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (list *List[T]) All(f func(index int, value T) bool) bool {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Index(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (index,value) for which the function is true or -1,nil otherwise\n// if no element matches the criteria.\nfunc (list *List[T]) Find(f func(index int, value T) bool) (index int, value T) {\n\titerator := list.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn iterator.Index(), iterator.Value()\n\t\t}\n\t}\n\treturn -1, value\n}\n"
  },
  {
    "path": "lists/singlylinkedlist/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage singlylinkedlist\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.IteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[T comparable] struct {\n\tlist    *List[T]\n\tindex   int\n\telement *element[T]\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (list *List[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{list: list, index: -1, element: nil}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.list.size {\n\t\titerator.index++\n\t}\n\tif !iterator.list.withinRange(iterator.index) {\n\t\titerator.element = nil\n\t\treturn false\n\t}\n\tif iterator.index == 0 {\n\t\titerator.element = iterator.list.first\n\t} else {\n\t\titerator.element = iterator.element.next\n\t}\n\treturn true\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\treturn iterator.element.value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n\titerator.element = nil\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "lists/singlylinkedlist/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage singlylinkedlist\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*List[int])(nil)\nvar _ containers.JSONDeserializer = (*List[int])(nil)\n\n// ToJSON outputs the JSON representation of list's elements.\nfunc (list *List[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(list.Values())\n}\n\n// FromJSON populates list's elements from the input JSON representation.\nfunc (list *List[T]) FromJSON(data []byte) error {\n\tvar elements []T\n\terr := json.Unmarshal(data, &elements)\n\tif err == nil {\n\t\tlist.Clear()\n\t\tlist.Add(elements...)\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (list *List[T]) UnmarshalJSON(bytes []byte) error {\n\treturn list.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (list *List[T]) MarshalJSON() ([]byte, error) {\n\treturn list.ToJSON()\n}\n"
  },
  {
    "path": "lists/singlylinkedlist/singlylinkedlist.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package singlylinkedlist implements the singly-linked list.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29\npackage singlylinkedlist\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert List implementation\nvar _ lists.List[int] = (*List[int])(nil)\n\n// List holds the elements, where each element points to the next element\ntype List[T comparable] struct {\n\tfirst *element[T]\n\tlast  *element[T]\n\tsize  int\n}\n\ntype element[T comparable] struct {\n\tvalue T\n\tnext  *element[T]\n}\n\n// New instantiates a new list and adds the passed values, if any, to the list\nfunc New[T comparable](values ...T) *List[T] {\n\tlist := &List[T]{}\n\tif len(values) > 0 {\n\t\tlist.Add(values...)\n\t}\n\treturn list\n}\n\n// Add appends a value (one or more) at the end of the list (same as Append())\nfunc (list *List[T]) Add(values ...T) {\n\tfor _, value := range values {\n\t\tnewElement := &element[T]{value: value}\n\t\tif list.size == 0 {\n\t\t\tlist.first = newElement\n\t\t\tlist.last = newElement\n\t\t} else {\n\t\t\tlist.last.next = newElement\n\t\t\tlist.last = newElement\n\t\t}\n\t\tlist.size++\n\t}\n}\n\n// Append appends a value (one or more) at the end of the list (same as Add())\nfunc (list *List[T]) Append(values ...T) {\n\tlist.Add(values...)\n}\n\n// Prepend prepends a values (or more)\nfunc (list *List[T]) Prepend(values ...T) {\n\t// in reverse to keep passed order i.e. [\"c\",\"d\"] -> Prepend([\"a\",\"b\"]) -> [\"a\",\"b\",\"c\",d\"]\n\tfor v := len(values) - 1; v >= 0; v-- {\n\t\tnewElement := &element[T]{value: values[v], next: list.first}\n\t\tlist.first = newElement\n\t\tif list.size == 0 {\n\t\t\tlist.last = newElement\n\t\t}\n\t\tlist.size++\n\t}\n}\n\n// Get returns the element at index.\n// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.\nfunc (list *List[T]) Get(index int) (T, bool) {\n\n\tif !list.withinRange(index) {\n\t\tvar t T\n\t\treturn t, false\n\t}\n\n\telement := list.first\n\tfor e := 0; e != index; e, element = e+1, element.next {\n\t}\n\n\treturn element.value, true\n}\n\n// Remove removes the element at the given index from the list.\nfunc (list *List[T]) Remove(index int) {\n\n\tif !list.withinRange(index) {\n\t\treturn\n\t}\n\n\tif list.size == 1 {\n\t\tlist.Clear()\n\t\treturn\n\t}\n\n\tvar beforeElement *element[T]\n\telement := list.first\n\tfor e := 0; e != index; e, element = e+1, element.next {\n\t\tbeforeElement = element\n\t}\n\n\tif element == list.first {\n\t\tlist.first = element.next\n\t}\n\tif element == list.last {\n\t\tlist.last = beforeElement\n\t}\n\tif beforeElement != nil {\n\t\tbeforeElement.next = element.next\n\t}\n\n\telement = nil\n\n\tlist.size--\n}\n\n// Contains checks if values (one or more) are present in the set.\n// All values have to be present in the set for the method to return true.\n// Performance time complexity of n^2.\n// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set.\nfunc (list *List[T]) Contains(values ...T) bool {\n\n\tif len(values) == 0 {\n\t\treturn true\n\t}\n\tif list.size == 0 {\n\t\treturn false\n\t}\n\tfor _, value := range values {\n\t\tfound := false\n\t\tfor element := list.first; element != nil; element = element.next {\n\t\t\tif element.value == value {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Values returns all elements in the list.\nfunc (list *List[T]) Values() []T {\n\tvalues := make([]T, list.size, list.size)\n\tfor e, element := 0, list.first; element != nil; e, element = e+1, element.next {\n\t\tvalues[e] = element.value\n\t}\n\treturn values\n}\n\n// IndexOf returns index of provided element\nfunc (list *List[T]) IndexOf(value T) int {\n\tif list.size == 0 {\n\t\treturn -1\n\t}\n\tfor index, element := range list.Values() {\n\t\tif element == value {\n\t\t\treturn index\n\t\t}\n\t}\n\treturn -1\n}\n\n// Empty returns true if list does not contain any elements.\nfunc (list *List[T]) Empty() bool {\n\treturn list.size == 0\n}\n\n// Size returns number of elements within the list.\nfunc (list *List[T]) Size() int {\n\treturn list.size\n}\n\n// Clear removes all elements from the list.\nfunc (list *List[T]) Clear() {\n\tlist.size = 0\n\tlist.first = nil\n\tlist.last = nil\n}\n\n// Sort sort values (in-place) using.\nfunc (list *List[T]) Sort(comparator utils.Comparator[T]) {\n\n\tif list.size < 2 {\n\t\treturn\n\t}\n\n\tvalues := list.Values()\n\tslices.SortFunc(values, comparator)\n\n\tlist.Clear()\n\n\tlist.Add(values...)\n\n}\n\n// Swap swaps values of two elements at the given indices.\nfunc (list *List[T]) Swap(i, j int) {\n\tif list.withinRange(i) && list.withinRange(j) && i != j {\n\t\tvar element1, element2 *element[T]\n\t\tfor e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next {\n\t\t\tswitch e {\n\t\t\tcase i:\n\t\t\t\telement1 = currentElement\n\t\t\tcase j:\n\t\t\t\telement2 = currentElement\n\t\t\t}\n\t\t}\n\t\telement1.value, element2.value = element2.value, element1.value\n\t}\n}\n\n// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right.\n// Does not do anything if position is negative or bigger than list's size\n// Note: position equal to list's size is valid, i.e. append.\nfunc (list *List[T]) Insert(index int, values ...T) {\n\n\tif !list.withinRange(index) {\n\t\t// Append\n\t\tif index == list.size {\n\t\t\tlist.Add(values...)\n\t\t}\n\t\treturn\n\t}\n\n\tlist.size += len(values)\n\n\tvar beforeElement *element[T]\n\tfoundElement := list.first\n\tfor e := 0; e != index; e, foundElement = e+1, foundElement.next {\n\t\tbeforeElement = foundElement\n\t}\n\n\tif foundElement == list.first {\n\t\toldNextElement := list.first\n\t\tfor i, value := range values {\n\t\t\tnewElement := &element[T]{value: value}\n\t\t\tif i == 0 {\n\t\t\t\tlist.first = newElement\n\t\t\t} else {\n\t\t\t\tbeforeElement.next = newElement\n\t\t\t}\n\t\t\tbeforeElement = newElement\n\t\t}\n\t\tbeforeElement.next = oldNextElement\n\t} else {\n\t\toldNextElement := beforeElement.next\n\t\tfor _, value := range values {\n\t\t\tnewElement := &element[T]{value: value}\n\t\t\tbeforeElement.next = newElement\n\t\t\tbeforeElement = newElement\n\t\t}\n\t\tbeforeElement.next = oldNextElement\n\t}\n}\n\n// Set value at specified index\n// Does not do anything if position is negative or bigger than list's size\n// Note: position equal to list's size is valid, i.e. append.\nfunc (list *List[T]) Set(index int, value T) {\n\n\tif !list.withinRange(index) {\n\t\t// Append\n\t\tif index == list.size {\n\t\t\tlist.Add(value)\n\t\t}\n\t\treturn\n\t}\n\n\tfoundElement := list.first\n\tfor e := 0; e != index; {\n\t\te, foundElement = e+1, foundElement.next\n\t}\n\tfoundElement.value = value\n}\n\n// String returns a string representation of container\nfunc (list *List[T]) String() string {\n\tstr := \"SinglyLinkedList\\n\"\n\tvalues := []string{}\n\tfor element := list.first; element != nil; element = element.next {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", element.value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (list *List[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < list.size\n}\n"
  },
  {
    "path": "lists/singlylinkedlist/singlylinkedlist_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage singlylinkedlist\n\nimport (\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestListNew(t *testing.T) {\n\tlist1 := New[int]()\n\n\tif actualValue := list1.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\tlist2 := New[int](1, 2)\n\n\tif actualValue := list2.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\n\tif actualValue, ok := list2.Get(0); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\n\tif actualValue, ok := list2.Get(1); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\n\tif actualValue, ok := list2.Get(2); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListAdd(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue := list.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListAppendAndPrepend(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"b\")\n\tlist.Prepend(\"a\")\n\tlist.Append(\"c\")\n\tif actualValue := list.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := list.Get(0); actualValue != \"a\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(1); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListRemove(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tlist.Remove(2)\n\tif actualValue, ok := list.Get(2); actualValue != \"\" || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"\")\n\t}\n\tlist.Remove(1)\n\tlist.Remove(0)\n\tlist.Remove(0) // no effect\n\tif actualValue := list.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListGet(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue, ok := list.Get(0); actualValue != \"a\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"a\")\n\t}\n\tif actualValue, ok := list.Get(1); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n\tif actualValue, ok := list.Get(2); actualValue != \"c\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n\tif actualValue, ok := list.Get(3); actualValue != \"\" || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"\")\n\t}\n\tlist.Remove(0)\n\tif actualValue, ok := list.Get(0); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n}\n\nfunc TestListSwap(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tlist.Swap(0, 1)\n\tif actualValue, ok := list.Get(0); actualValue != \"b\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n}\n\nfunc TestListSort(t *testing.T) {\n\tlist := New[string]()\n\tlist.Sort(cmp.Compare[string])\n\tlist.Add(\"e\", \"f\", \"g\", \"a\", \"b\", \"c\", \"d\")\n\tlist.Sort(cmp.Compare[string])\n\tfor i := 1; i < list.Size(); i++ {\n\t\ta, _ := list.Get(i - 1)\n\t\tb, _ := list.Get(i)\n\t\tif a > b {\n\t\t\tt.Errorf(\"Not sorted! %s > %s\", a, b)\n\t\t}\n\t}\n}\n\nfunc TestListClear(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"e\", \"f\", \"g\", \"a\", \"b\", \"c\", \"d\")\n\tlist.Clear()\n\tif actualValue := list.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestListContains(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue := list.Contains(\"a\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Contains(\"\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\", \"d\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tlist.Clear()\n\tif actualValue := list.Contains(\"a\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := list.Contains(\"a\", \"b\", \"c\"); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n}\n\nfunc TestListValues(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListIndexOf(t *testing.T) {\n\tlist := New[string]()\n\n\texpectedIndex := -1\n\tif index := list.IndexOf(\"a\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n\n\tlist.Add(\"a\")\n\tlist.Add(\"b\", \"c\")\n\n\texpectedIndex = 0\n\tif index := list.IndexOf(\"a\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n\n\texpectedIndex = 1\n\tif index := list.IndexOf(\"b\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n\n\texpectedIndex = 2\n\tif index := list.IndexOf(\"c\"); index != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", index, expectedIndex)\n\t}\n}\n\nfunc TestListInsert(t *testing.T) {\n\tlist := New[string]()\n\tlist.Insert(0, \"b\", \"c\")\n\tlist.Insert(0, \"a\")\n\tlist.Insert(10, \"x\") // ignore\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tlist.Insert(3, \"d\") // append\n\tif actualValue := list.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\tif actualValue, expectedValue := strings.Join(list.Values(), \"\"), \"abcd\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListSet(t *testing.T) {\n\tlist := New[string]()\n\tlist.Set(0, \"a\")\n\tlist.Set(1, \"b\")\n\tif actualValue := list.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tlist.Set(2, \"c\") // append\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tlist.Set(4, \"d\")  // ignore\n\tlist.Set(1, \"bb\") // update\n\tif actualValue := list.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"bb\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListEach(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tlist.Each(func(index int, value string) {\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestListMap(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tmappedList := list.Map(func(index int, value string) string {\n\t\treturn \"mapped: \" + value\n\t})\n\tif actualValue, _ := mappedList.Get(0); actualValue != \"mapped: a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: a\")\n\t}\n\tif actualValue, _ := mappedList.Get(1); actualValue != \"mapped: b\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: b\")\n\t}\n\tif actualValue, _ := mappedList.Get(2); actualValue != \"mapped: c\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: c\")\n\t}\n\tif mappedList.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedList.Size(), 3)\n\t}\n}\n\nfunc TestListSelect(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tselectedList := list.Select(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif actualValue, _ := selectedList.Get(0); actualValue != \"a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: a\")\n\t}\n\tif actualValue, _ := selectedList.Get(1); actualValue != \"b\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: b\")\n\t}\n\tif selectedList.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedList.Size(), 3)\n\t}\n}\n\nfunc TestListAny(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tany := list.Any(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = list.Any(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\nfunc TestListAll(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tall := list.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = list.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\nfunc TestListFind(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tfoundIndex, foundValue := list.Find(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif foundValue != \"c\" || foundIndex != 2 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, \"c\", 2)\n\t}\n\tfoundIndex, foundValue = list.Find(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif foundValue != \"\" || foundIndex != -1 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, nil, nil)\n\t}\n}\nfunc TestListChaining(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tchainedList := list.Select(func(index int, value string) bool {\n\t\treturn value > \"a\"\n\t}).Map(func(index int, value string) string {\n\t\treturn value + value\n\t})\n\tif chainedList.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", chainedList.Size(), 2)\n\t}\n\tif actualValue, ok := chainedList.Get(0); actualValue != \"bb\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"b\")\n\t}\n\tif actualValue, ok := chainedList.Get(1); actualValue != \"cc\" || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"c\")\n\t}\n}\n\nfunc TestListIteratorNextOnEmpty(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t}\n}\n\nfunc TestListIteratorNext(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tit := list.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestListIteratorBegin(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tit.Begin()\n\tlist.Add(\"a\", \"b\", \"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestListIteratorFirst(t *testing.T) {\n\tlist := New[string]()\n\tit := list.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tlist.Add(\"a\", \"b\", \"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestListIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tlist := New[string]()\n\t\tit := list.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"xx\", \"yy\")\n\t\tit := list.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tlist := New[string]()\n\t\tlist.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := list.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestListSerialization(t *testing.T) {\n\tlist := New[string]()\n\tlist.Add(\"a\", \"b\", \"c\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := list.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := list.ToJSON()\n\tassert()\n\n\terr = list.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]any{\"a\", \"b\", \"c\", list})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &list)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestListString(t *testing.T) {\n\tc := New[int]()\n\tc.Add(1)\n\tif !strings.HasPrefix(c.String(), \"SinglyLinkedList\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkAdd(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Add(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, list *List[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tlist.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkSinglyLinkedListGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListAdd100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListAdd1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListAdd10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListAdd100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n\nfunc BenchmarkSinglyLinkedListRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tlist := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tlist.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, list, size)\n}\n"
  },
  {
    "path": "maps/hashbidimap/hashbidimap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package hashbidimap implements a bidirectional map backed by two hashmaps.\n//\n// A bidirectional map, or hash bag, is an associative data structure in which the (key,value) pairs form a one-to-one correspondence.\n// Thus the binary relation is functional in each direction: value can also act as a key to key.\n// 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.\n//\n// Elements are unordered in the map.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/Bidirectional_map\npackage hashbidimap\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/maps\"\n\t\"github.com/emirpasic/gods/v2/maps/hashmap\"\n)\n\n// Assert Map implementation\nvar _ maps.BidiMap[string, int] = (*Map[string, int])(nil)\n\n// Map holds the elements in two hashmaps.\ntype Map[K, V comparable] struct {\n\tforwardMap hashmap.Map[K, V]\n\tinverseMap hashmap.Map[V, K]\n}\n\n// New instantiates a bidirectional map.\nfunc New[K, V comparable]() *Map[K, V] {\n\treturn &Map[K, V]{*hashmap.New[K, V](), *hashmap.New[V, K]()}\n}\n\n// Put inserts element into the map.\nfunc (m *Map[K, V]) Put(key K, value V) {\n\tif valueByKey, ok := m.forwardMap.Get(key); ok {\n\t\tm.inverseMap.Remove(valueByKey)\n\t}\n\tif keyByValue, ok := m.inverseMap.Get(value); ok {\n\t\tm.forwardMap.Remove(keyByValue)\n\t}\n\tm.forwardMap.Put(key, value)\n\tm.inverseMap.Put(value, key)\n}\n\n// Get searches the element in the map by key and returns its value or nil if key is not found in map.\n// Second return parameter is true if key was found, otherwise false.\nfunc (m *Map[K, V]) Get(key K) (value V, found bool) {\n\treturn m.forwardMap.Get(key)\n}\n\n// GetKey searches the element in the map by value and returns its key or nil if value is not found in map.\n// Second return parameter is true if value was found, otherwise false.\nfunc (m *Map[K, V]) GetKey(value V) (key K, found bool) {\n\treturn m.inverseMap.Get(value)\n}\n\n// Remove removes the element from the map by key.\nfunc (m *Map[K, V]) Remove(key K) {\n\tif value, found := m.forwardMap.Get(key); found {\n\t\tm.forwardMap.Remove(key)\n\t\tm.inverseMap.Remove(value)\n\t}\n}\n\n// Empty returns true if map does not contain any elements\nfunc (m *Map[K, V]) Empty() bool {\n\treturn m.Size() == 0\n}\n\n// Size returns number of elements in the map.\nfunc (m *Map[K, V]) Size() int {\n\treturn m.forwardMap.Size()\n}\n\n// Keys returns all keys (random order).\nfunc (m *Map[K, V]) Keys() []K {\n\treturn m.forwardMap.Keys()\n}\n\n// Values returns all values (random order).\nfunc (m *Map[K, V]) Values() []V {\n\treturn m.inverseMap.Keys()\n}\n\n// Clear removes all elements from the map.\nfunc (m *Map[K, V]) Clear() {\n\tm.forwardMap.Clear()\n\tm.inverseMap.Clear()\n}\n\n// String returns a string representation of container\nfunc (m *Map[K, V]) String() string {\n\tstr := \"HashBidiMap\\n\"\n\tstr += fmt.Sprintf(\"%v\", m.forwardMap)\n\treturn str\n}\n"
  },
  {
    "path": "maps/hashbidimap/hashbidimap_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage hashbidimap\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestMapPut(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tif actualValue := m.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4, 5, 6, 7})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"})\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestMapRemove(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tm.Remove(5)\n\tm.Remove(6)\n\tm.Remove(7)\n\tm.Remove(8)\n\tm.Remove(5)\n\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\"})\n\n\tif actualValue := m.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\tm.Remove(1)\n\tm.Remove(4)\n\tm.Remove(2)\n\tm.Remove(3)\n\tm.Remove(2)\n\tm.Remove(2)\n\n\ttestutils.SameElements(t, m.Keys(), nil)\n\ttestutils.SameElements(t, m.Values(), nil)\n\tif actualValue := m.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\tif actualValue := m.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestMapGetKey(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{0, \"x\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.GetKey(test[1].(string))\n\t\tif actualValue != test[0] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[0])\n\t\t}\n\t}\n}\n\nfunc TestMapSerialization(t *testing.T) {\n\tm := New[string, float64]()\n\tm.Put(\"a\", 1.0)\n\tm.Put(\"b\", 2.0)\n\tm.Put(\"c\", 3.0)\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, m.Keys(), []string{\"a\", \"b\", \"c\"})\n\t\ttestutils.SameElements(t, m.Values(), []float64{1.0, 2.0, 3.0})\n\t\tif actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := m.ToJSON()\n\tassert()\n\n\terr = m.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", m})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), &m)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n}\n\nfunc TestMapString(t *testing.T) {\n\tc := New[string, int]()\n\tc.Put(\"a\", 1)\n\tif !strings.HasPrefix(c.String(), \"HashBidiMap\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Put(n, n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkHashBidiMapGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapPut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapPut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapPut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapPut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkHashBidiMapRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n"
  },
  {
    "path": "maps/hashbidimap/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage hashbidimap\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Map[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Map[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the map.\nfunc (m *Map[K, V]) ToJSON() ([]byte, error) {\n\treturn m.forwardMap.ToJSON()\n}\n\n// FromJSON populates the map from the input JSON representation.\nfunc (m *Map[K, V]) FromJSON(data []byte) error {\n\tvar elements map[K]V\n\terr := json.Unmarshal(data, &elements)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tm.Clear()\n\tfor k, v := range elements {\n\t\tm.Put(k, v)\n\t}\n\n\treturn nil\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (m *Map[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn m.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (m *Map[K, V]) MarshalJSON() ([]byte, error) {\n\treturn m.ToJSON()\n}\n"
  },
  {
    "path": "maps/hashmap/hashmap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package hashmap implements a map backed by a hash table.\n//\n// Elements are unordered in the map.\n//\n// Structure is not thread safe.\n//\n// Reference: http://en.wikipedia.org/wiki/Associative_array\npackage hashmap\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/maps\"\n)\n\n// Assert Map implementation\nvar _ maps.Map[string, int] = (*Map[string, int])(nil)\n\n// Map holds the elements in go's native map\ntype Map[K comparable, V any] struct {\n\tm map[K]V\n}\n\n// New instantiates a hash map.\nfunc New[K comparable, V any]() *Map[K, V] {\n\treturn &Map[K, V]{m: make(map[K]V)}\n}\n\n// Put inserts element into the map.\nfunc (m *Map[K, V]) Put(key K, value V) {\n\tm.m[key] = value\n}\n\n// Get searches the element in the map by key and returns its value or nil if key is not found in map.\n// Second return parameter is true if key was found, otherwise false.\nfunc (m *Map[K, V]) Get(key K) (value V, found bool) {\n\tvalue, found = m.m[key]\n\treturn\n}\n\n// Remove removes the element from the map by key.\nfunc (m *Map[K, V]) Remove(key K) {\n\tdelete(m.m, key)\n}\n\n// Empty returns true if map does not contain any elements\nfunc (m *Map[K, V]) Empty() bool {\n\treturn m.Size() == 0\n}\n\n// Size returns number of elements in the map.\nfunc (m *Map[K, V]) Size() int {\n\treturn len(m.m)\n}\n\n// Keys returns all keys (random order).\nfunc (m *Map[K, V]) Keys() []K {\n\tkeys := make([]K, m.Size())\n\tcount := 0\n\tfor key := range m.m {\n\t\tkeys[count] = key\n\t\tcount++\n\t}\n\treturn keys\n}\n\n// Values returns all values (random order).\nfunc (m *Map[K, V]) Values() []V {\n\tvalues := make([]V, m.Size())\n\tcount := 0\n\tfor _, value := range m.m {\n\t\tvalues[count] = value\n\t\tcount++\n\t}\n\treturn values\n}\n\n// Clear removes all elements from the map.\nfunc (m *Map[K, V]) Clear() {\n\tclear(m.m)\n}\n\n// String returns a string representation of container\nfunc (m *Map[K, V]) String() string {\n\tstr := \"HashMap\\n\"\n\tstr += fmt.Sprintf(\"%v\", m.m)\n\treturn str\n}\n"
  },
  {
    "path": "maps/hashmap/hashmap_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage hashmap\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestMapPut(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tif actualValue := m.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4, 5, 6, 7})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"})\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestMapRemove(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tm.Remove(5)\n\tm.Remove(6)\n\tm.Remove(7)\n\tm.Remove(8)\n\tm.Remove(5)\n\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\"})\n\n\tif actualValue := m.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\tm.Remove(1)\n\tm.Remove(4)\n\tm.Remove(2)\n\tm.Remove(3)\n\tm.Remove(2)\n\tm.Remove(2)\n\n\ttestutils.SameElements(t, m.Keys(), nil)\n\ttestutils.SameElements(t, m.Values(), nil)\n\tif actualValue := m.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\tif actualValue := m.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestMapSerialization(t *testing.T) {\n\tm := New[string, float64]()\n\tm.Put(\"a\", 1.0)\n\tm.Put(\"b\", 2.0)\n\tm.Put(\"c\", 3.0)\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, m.Keys(), []string{\"a\", \"b\", \"c\"})\n\t\ttestutils.SameElements(t, m.Values(), []float64{1.0, 2.0, 3.0})\n\t\tif actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := m.ToJSON()\n\tassert()\n\n\terr = m.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", m})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), &m)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n}\n\nfunc TestMapString(t *testing.T) {\n\tc := New[string, int]()\n\tc.Put(\"a\", 1)\n\tif !strings.HasPrefix(c.String(), \"HashMap\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Put(n, n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkHashMapGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashMapGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashMapGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashMapGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkHashMapPut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashMapPut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashMapPut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashMapPut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkHashMapRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkHashMapRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkHashMapRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkHashMapRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n"
  },
  {
    "path": "maps/hashmap/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage hashmap\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Map[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Map[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the map.\nfunc (m *Map[K, V]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(m.m)\n}\n\n// FromJSON populates the map from the input JSON representation.\nfunc (m *Map[K, V]) FromJSON(data []byte) error {\n\treturn json.Unmarshal(data, &m.m)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (m *Map[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn m.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (m *Map[K, V]) MarshalJSON() ([]byte, error) {\n\treturn m.ToJSON()\n}\n"
  },
  {
    "path": "maps/linkedhashmap/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashmap\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithKey[string, int] = (*Map[string, int])(nil)\n\n// Each calls the given function once for each element, passing that element's key and value.\nfunc (m *Map[K, V]) Each(f func(key K, value V)) {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Key(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a container\n// containing the values returned by the given function as key/value pairs.\nfunc (m *Map[K, V]) Map(f func(key1 K, value1 V) (K, V)) *Map[K, V] {\n\tnewMap := New[K, V]()\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tkey2, value2 := f(iterator.Key(), iterator.Value())\n\t\tnewMap.Put(key2, value2)\n\t}\n\treturn newMap\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (m *Map[K, V]) Select(f func(key K, value V) bool) *Map[K, V] {\n\tnewMap := New[K, V]()\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\tnewMap.Put(iterator.Key(), iterator.Value())\n\t\t}\n\t}\n\treturn newMap\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (m *Map[K, V]) Any(f func(key K, value V) bool) bool {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (m *Map[K, V]) All(f func(key K, value V) bool) bool {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Key(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (key,value) for which the function is true or nil,nil otherwise if no element\n// matches the criteria.\nfunc (m *Map[K, V]) Find(f func(key K, value V) bool) (k K, v V) {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\treturn iterator.Key(), iterator.Value()\n\t\t}\n\t}\n\treturn k, v\n}\n"
  },
  {
    "path": "maps/linkedhashmap/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashmap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\t\"github.com/emirpasic/gods/v2/lists/doublylinkedlist\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithKey[string, int] = (*Iterator[string, int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[K comparable, V any] struct {\n\titerator doublylinkedlist.Iterator[K]\n\ttable    map[K]V\n}\n\n// Iterator returns a stateful iterator whose elements are key/value pairs.\nfunc (m *Map[K, V]) Iterator() *Iterator[K, V] {\n\treturn &Iterator[K, V]{\n\t\titerator: m.ordering.Iterator(),\n\t\ttable:    m.table,\n\t}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Next() bool {\n\treturn iterator.iterator.Next()\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Prev() bool {\n\treturn iterator.iterator.Prev()\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Value() V {\n\tkey := iterator.iterator.Value()\n\treturn iterator.table[key]\n}\n\n// Key returns the current element's key.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Key() K {\n\treturn iterator.iterator.Value()\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[K, V]) Begin() {\n\titerator.iterator.Begin()\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[K, V]) End() {\n\titerator.iterator.End()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator\nfunc (iterator *Iterator[K, V]) First() bool {\n\treturn iterator.iterator.First()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Last() bool {\n\treturn iterator.iterator.Last()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) NextTo(f func(key K, value V) bool) bool {\n\tfor iterator.Next() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) PrevTo(f func(key K, value V) bool) bool {\n\tfor iterator.Prev() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "maps/linkedhashmap/linkedhashmap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package linkedhashmap is a map that preserves insertion-order.\n//\n// It is backed by a hash table to store values and doubly-linked list to store ordering.\n//\n// Structure is not thread safe.\n//\n// Reference: http://en.wikipedia.org/wiki/Associative_array\npackage linkedhashmap\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/doublylinkedlist\"\n\t\"github.com/emirpasic/gods/v2/maps\"\n)\n\n// Assert Map implementation\nvar _ maps.Map[string, int] = (*Map[string, int])(nil)\n\n// Map holds the elements in a regular hash table, and uses doubly-linked list to store key ordering.\ntype Map[K comparable, V any] struct {\n\ttable    map[K]V\n\tordering *doublylinkedlist.List[K]\n}\n\n// New instantiates a linked-hash-map.\nfunc New[K comparable, V any]() *Map[K, V] {\n\treturn &Map[K, V]{\n\t\ttable:    make(map[K]V),\n\t\tordering: doublylinkedlist.New[K](),\n\t}\n}\n\n// Put inserts key-value pair into the map.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Put(key K, value V) {\n\tif _, contains := m.table[key]; !contains {\n\t\tm.ordering.Append(key)\n\t}\n\tm.table[key] = value\n}\n\n// Get searches the element in the map by key and returns its value or nil if key is not found in tree.\n// Second return parameter is true if key was found, otherwise false.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Get(key K) (value V, found bool) {\n\tvalue, found = m.table[key]\n\treturn value, found\n}\n\n// Remove removes the element from the map by key.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Remove(key K) {\n\tif _, contains := m.table[key]; contains {\n\t\tdelete(m.table, key)\n\t\tindex := m.ordering.IndexOf(key)\n\t\tm.ordering.Remove(index)\n\t}\n}\n\n// Empty returns true if map does not contain any elements\nfunc (m *Map[K, V]) Empty() bool {\n\treturn m.Size() == 0\n}\n\n// Size returns number of elements in the map.\nfunc (m *Map[K, V]) Size() int {\n\treturn m.ordering.Size()\n}\n\n// Keys returns all keys in-order\nfunc (m *Map[K, V]) Keys() []K {\n\treturn m.ordering.Values()\n}\n\n// Values returns all values in-order based on the key.\nfunc (m *Map[K, V]) Values() []V {\n\tvalues := make([]V, m.Size())\n\tcount := 0\n\tit := m.Iterator()\n\tfor it.Next() {\n\t\tvalues[count] = it.Value()\n\t\tcount++\n\t}\n\treturn values\n}\n\n// Clear removes all elements from the map.\nfunc (m *Map[K, V]) Clear() {\n\tclear(m.table)\n\tm.ordering.Clear()\n}\n\n// String returns a string representation of container\nfunc (m *Map[K, V]) String() string {\n\tstr := \"LinkedHashMap\\nmap[\"\n\tit := m.Iterator()\n\tfor it.Next() {\n\t\tstr += fmt.Sprintf(\"%v:%v \", it.Key(), it.Value())\n\t}\n\treturn strings.TrimRight(str, \" \") + \"]\"\n\n}\n"
  },
  {
    "path": "maps/linkedhashmap/linkedhashmap_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashmap\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestMapPut(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tif actualValue := m.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4, 5, 6, 7})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"})\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestMapRemove(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tm.Remove(5)\n\tm.Remove(6)\n\tm.Remove(7)\n\tm.Remove(8)\n\tm.Remove(5)\n\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\"})\n\n\tif actualValue := m.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\tm.Remove(1)\n\tm.Remove(4)\n\tm.Remove(2)\n\tm.Remove(3)\n\tm.Remove(2)\n\tm.Remove(2)\n\n\ttestutils.SameElements(t, m.Keys(), nil)\n\ttestutils.SameElements(t, m.Values(), nil)\n\tif actualValue := m.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\tif actualValue := m.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestMapEach(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 1)\n\tm.Put(\"a\", 2)\n\tm.Put(\"b\", 3)\n\tcount := 0\n\tm.Each(func(key string, value int) {\n\t\tcount++\n\t\tif actualValue, expectedValue := count, value; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tswitch value {\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := key, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := key, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 3:\n\t\t\tif actualValue, expectedValue := key, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestMapMap(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tmappedMap := m.Map(func(key1 string, value1 int) (key2 string, value2 int) {\n\t\treturn key1, value1 * value1\n\t})\n\tif actualValue, _ := mappedMap.Get(\"c\"); actualValue != 9 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: c\")\n\t}\n\tif actualValue, _ := mappedMap.Get(\"a\"); actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: a\")\n\t}\n\tif actualValue, _ := mappedMap.Get(\"b\"); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: b\")\n\t}\n\tif mappedMap.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedMap.Size(), 3)\n\t}\n}\n\nfunc TestMapSelect(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"b\", 1)\n\tm.Put(\"a\", 2)\n\tselectedMap := m.Select(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"b\"\n\t})\n\tif actualValue, _ := selectedMap.Get(\"b\"); actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: a\")\n\t}\n\tif actualValue, _ := selectedMap.Get(\"a\"); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: b\")\n\t}\n\tif selectedMap.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedMap.Size(), 2)\n\t}\n}\n\nfunc TestMapAny(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tany := m.Any(func(key string, value int) bool {\n\t\treturn value == 3\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = m.Any(func(key string, value int) bool {\n\t\treturn value == 4\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\n\nfunc TestMapAll(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tall := m.All(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = m.All(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\n\nfunc TestMapFind(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tfoundKey, foundValue := m.Find(func(key string, value int) bool {\n\t\treturn key == \"c\"\n\t})\n\tif foundKey != \"c\" || foundValue != 3 {\n\t\tt.Errorf(\"Got %v -> %v expected %v -> %v\", foundKey, foundValue, \"c\", 3)\n\t}\n\tfoundKey, foundValue = m.Find(func(key string, value int) bool {\n\t\treturn key == \"x\"\n\t})\n\tif foundKey != \"\" || foundValue != 0 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundKey, \"\", 0)\n\t}\n}\n\nfunc TestMapChaining(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tchainedMap := m.Select(func(key string, value int) bool {\n\t\treturn value > 1\n\t}).Map(func(key string, value int) (string, int) {\n\t\treturn key + key, value * value\n\t})\n\tif actualValue := chainedMap.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, found := chainedMap.Get(\"aa\"); actualValue != 0 || found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue, found := chainedMap.Get(\"bb\"); actualValue != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\tif actualValue, found := chainedMap.Get(\"cc\"); actualValue != 9 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 9)\n\t}\n}\n\nfunc TestMapIteratorNextOnEmpty(t *testing.T) {\n\tm := New[string, int]()\n\tit := m.Iterator()\n\tit = m.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t}\n}\n\nfunc TestMapIteratorPrevOnEmpty(t *testing.T) {\n\tm := New[string, int]()\n\tit := m.Iterator()\n\tit = m.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t}\n}\n\nfunc TestMapIteratorNext(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 1)\n\tm.Put(\"a\", 2)\n\tm.Put(\"b\", 3)\n\n\tit := m.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tvalue := it.Value()\n\t\tswitch key {\n\t\tcase \"c\":\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"a\":\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"b\":\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapIteratorPrev(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 1)\n\tm.Put(\"a\", 2)\n\tm.Put(\"b\", 3)\n\n\tit := m.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := m.Size()\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tvalue := it.Value()\n\t\tswitch key {\n\t\tcase \"c\":\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"a\":\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"b\":\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := value, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapIteratorBegin(t *testing.T) {\n\tm := New[int, string]()\n\tit := m.Iterator()\n\tit.Begin()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestMapIteratorEnd(t *testing.T) {\n\tm := New[int, string]()\n\tit := m.Iterator()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit.End()\n\tit.Prev()\n\tif key, value := it.Key(), it.Value(); key != 2 || value != \"b\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 2, \"b\")\n\t}\n}\n\nfunc TestMapIteratorFirst(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit := m.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestMapIteratorLast(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit := m.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 2 || value != \"b\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 2, \"b\")\n\t}\n}\n\nfunc TestMapIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tm := New[int, string]()\n\t\tit := m.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"xx\")\n\t\tm.Put(1, \"yy\")\n\t\tit := m.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"aa\")\n\t\tm.Put(1, \"bb\")\n\t\tm.Put(2, \"cc\")\n\t\tit := m.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestMapIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tm := New[int, string]()\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"xx\")\n\t\tm.Put(1, \"yy\")\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"aa\")\n\t\tm.Put(1, \"bb\")\n\t\tm.Put(2, \"cc\")\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestMapSerialization(t *testing.T) {\n\tfor i := 0; i < 10; i++ {\n\t\toriginal := New[string, string]()\n\t\toriginal.Put(\"d\", \"4\")\n\t\toriginal.Put(\"e\", \"5\")\n\t\toriginal.Put(\"c\", \"3\")\n\t\toriginal.Put(\"b\", \"2\")\n\t\toriginal.Put(\"a\", \"1\")\n\n\t\tserialized, err := original.ToJSON()\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\n\t\tdeserialized := New[string, string]()\n\t\terr = deserialized.FromJSON(serialized)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\n\t\tif original.Size() != deserialized.Size() {\n\t\t\tt.Errorf(\"Got map of size %d, expected %d\", original.Size(), deserialized.Size())\n\t\t}\n\t\toriginal.Each(func(key string, expected string) {\n\t\t\tactual, ok := deserialized.Get(key)\n\t\t\tif !ok || actual != expected {\n\t\t\t\tt.Errorf(\"Did not find expected value %v for key %v in deserialied map (got %v)\", expected, key, actual)\n\t\t\t}\n\t\t})\n\t}\n\n\tm := New[string, float64]()\n\tm.Put(\"a\", 1.0)\n\tm.Put(\"b\", 2.0)\n\tm.Put(\"c\", 3.0)\n\n\t_, err := json.Marshal([]interface{}{\"a\", \"b\", \"c\", m})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), &m)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n}\n\nfunc TestMapString(t *testing.T) {\n\tc := New[string, int]()\n\tc.Put(\"a\", 1)\n\tif !strings.HasPrefix(c.String(), \"LinkedHashMap\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Put(n, n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkTreeMapGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n"
  },
  {
    "path": "maps/linkedhashmap/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashmap\n\nimport (\n\t\"bytes\"\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"slices\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Map[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Map[string, int])(nil)\n\n// ToJSON outputs the JSON representation of map.\nfunc (m *Map[K, V]) ToJSON() ([]byte, error) {\n\tvar b []byte\n\tbuf := bytes.NewBuffer(b)\n\n\tbuf.WriteRune('{')\n\n\tit := m.Iterator()\n\tlastIndex := m.Size() - 1\n\tindex := 0\n\n\tfor it.Next() {\n\t\tkm, err := json.Marshal(it.Key())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbuf.Write(km)\n\n\t\tbuf.WriteRune(':')\n\n\t\tvm, err := json.Marshal(it.Value())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbuf.Write(vm)\n\n\t\tif index != lastIndex {\n\t\t\tbuf.WriteRune(',')\n\t\t}\n\n\t\tindex++\n\t}\n\n\tbuf.WriteRune('}')\n\n\treturn buf.Bytes(), nil\n}\n\n// FromJSON populates map from the input JSON representation.\n//func (m *Map[K, V]) FromJSON(data []byte) error {\n//\telements := make(map[string]interface{})\n//\terr := json.Unmarshal(data, &elements)\n//\tif err == nil {\n//\t\tm.Clear()\n//\t\tfor key, value := range elements {\n//\t\t\tm.Put(key, value)\n//\t\t}\n//\t}\n//\treturn err\n//}\n\n// FromJSON populates map from the input JSON representation.\nfunc (m *Map[K, V]) FromJSON(data []byte) error {\n\telements := make(map[K]V)\n\terr := json.Unmarshal(data, &elements)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tindex := make(map[K]int)\n\tvar keys []K\n\tfor key := range elements {\n\t\tkeys = append(keys, key)\n\t\tesc, _ := json.Marshal(key)\n\t\tindex[key] = bytes.Index(data, esc)\n\t}\n\n\tbyIndex := func(key1, key2 K) int {\n\t\treturn cmp.Compare(index[key1], index[key2])\n\t}\n\n\tslices.SortFunc(keys, byIndex)\n\n\tm.Clear()\n\n\tfor _, key := range keys {\n\t\tm.Put(key, elements[key])\n\t}\n\n\treturn nil\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (m *Map[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn m.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (m *Map[K, V]) MarshalJSON() ([]byte, error) {\n\treturn m.ToJSON()\n}\n"
  },
  {
    "path": "maps/maps.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package maps provides an abstract Map interface.\n//\n// 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.\n//\n// Operations associated with this data type allow:\n// - the addition of a pair to the collection\n// - the removal of a pair from the collection\n// - the modification of an existing pair\n// - the lookup of a value associated with a particular key\n//\n// Reference: https://en.wikipedia.org/wiki/Associative_array\npackage maps\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Map interface that all maps implement\ntype Map[K comparable, V any] interface {\n\tPut(key K, value V)\n\tGet(key K) (value V, found bool)\n\tRemove(key K)\n\tKeys() []K\n\n\tcontainers.Container[V]\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n\n// BidiMap interface that all bidirectional maps implement (extends the Map interface)\ntype BidiMap[K comparable, V comparable] interface {\n\tGetKey(value V) (key K, found bool)\n\n\tMap[K, V]\n}\n"
  },
  {
    "path": "maps/treebidimap/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treebidimap\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithKey[string, int] = (*Map[string, int])(nil)\n\n// Each calls the given function once for each element, passing that element's key and value.\nfunc (m *Map[K, V]) Each(f func(key K, value V)) {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Key(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a container\n// containing the values returned by the given function as key/value pairs.\nfunc (m *Map[K, V]) Map(f func(key1 K, value1 V) (K, V)) *Map[K, V] {\n\tnewMap := NewWith[K, V](m.forwardMap.Comparator, m.inverseMap.Comparator)\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tkey2, value2 := f(iterator.Key(), iterator.Value())\n\t\tnewMap.Put(key2, value2)\n\t}\n\treturn newMap\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (m *Map[K, V]) Select(f func(key K, value V) bool) *Map[K, V] {\n\tnewMap := NewWith[K, V](m.forwardMap.Comparator, m.inverseMap.Comparator)\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\tnewMap.Put(iterator.Key(), iterator.Value())\n\t\t}\n\t}\n\treturn newMap\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (m *Map[K, V]) Any(f func(key K, value V) bool) bool {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (m *Map[K, V]) All(f func(key K, value V) bool) bool {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Key(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (key,value) for which the function is true or nil,nil otherwise if no element\n// matches the criteria.\nfunc (m *Map[K, V]) Find(f func(key K, value V) bool) (k K, v V) {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\treturn iterator.Key(), iterator.Value()\n\t\t}\n\t}\n\treturn k, v\n}\n"
  },
  {
    "path": "maps/treebidimap/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treebidimap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithKey[string, int] = (*Iterator[string, int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[K comparable, V any] struct {\n\titerator *rbt.Iterator[K, V]\n}\n\n// Iterator returns a stateful iterator whose elements are key/value pairs.\nfunc (m *Map[K, V]) Iterator() *Iterator[K, V] {\n\treturn &Iterator[K, V]{iterator: m.forwardMap.Iterator()}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Next() bool {\n\treturn iterator.iterator.Next()\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Prev() bool {\n\treturn iterator.iterator.Prev()\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Value() V {\n\treturn iterator.iterator.Value()\n}\n\n// Key returns the current element's key.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Key() K {\n\treturn iterator.iterator.Key()\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[K, V]) Begin() {\n\titerator.iterator.Begin()\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[K, V]) End() {\n\titerator.iterator.End()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator\nfunc (iterator *Iterator[K, V]) First() bool {\n\treturn iterator.iterator.First()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Last() bool {\n\treturn iterator.iterator.Last()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) NextTo(f func(key K, value V) bool) bool {\n\tfor iterator.Next() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) PrevTo(f func(key K, value V) bool) bool {\n\tfor iterator.Prev() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "maps/treebidimap/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treebidimap\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Map[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Map[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the map.\nfunc (m *Map[K, V]) ToJSON() ([]byte, error) {\n\treturn m.forwardMap.ToJSON()\n}\n\n// FromJSON populates the map from the input JSON representation.\nfunc (m *Map[K, V]) FromJSON(data []byte) error {\n\tvar elements map[K]V\n\terr := json.Unmarshal(data, &elements)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tm.Clear()\n\tfor key, value := range elements {\n\t\tm.Put(key, value)\n\t}\n\n\treturn nil\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (m *Map[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn m.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (m *Map[K, V]) MarshalJSON() ([]byte, error) {\n\treturn m.ToJSON()\n}\n"
  },
  {
    "path": "maps/treebidimap/treebidimap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package treebidimap implements a bidirectional map backed by two red-black tree.\n//\n// This structure guarantees that the map will be in both ascending key and value order.\n//\n// 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.\n//\n// A bidirectional map, or hash bag, is an associative data structure in which the (key,value) pairs form a one-to-one correspondence.\n// Thus the binary relation is functional in each direction: value can also act as a key to key.\n// 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.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/Bidirectional_map\npackage treebidimap\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/maps\"\n\t\"github.com/emirpasic/gods/v2/trees/redblacktree\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Map implementation\nvar _ maps.BidiMap[string, int] = (*Map[string, int])(nil)\n\n// Map holds the elements in two red-black trees.\ntype Map[K, V comparable] struct {\n\tforwardMap redblacktree.Tree[K, V]\n\tinverseMap redblacktree.Tree[V, K]\n}\n\n// New instantiates a bidirectional map.\nfunc New[K, V cmp.Ordered]() *Map[K, V] {\n\treturn &Map[K, V]{\n\t\tforwardMap: *redblacktree.New[K, V](),\n\t\tinverseMap: *redblacktree.New[V, K](),\n\t}\n}\n\n// NewWith instantiates a bidirectional map.\nfunc NewWith[K, V comparable](keyComparator utils.Comparator[K], valueComparator utils.Comparator[V]) *Map[K, V] {\n\treturn &Map[K, V]{\n\t\tforwardMap: *redblacktree.NewWith[K, V](keyComparator),\n\t\tinverseMap: *redblacktree.NewWith[V, K](valueComparator),\n\t}\n}\n\n// Put inserts element into the map.\nfunc (m *Map[K, V]) Put(key K, value V) {\n\tif v, ok := m.forwardMap.Get(key); ok {\n\t\tm.inverseMap.Remove(v)\n\t}\n\tif k, ok := m.inverseMap.Get(value); ok {\n\t\tm.forwardMap.Remove(k)\n\t}\n\tm.forwardMap.Put(key, value)\n\tm.inverseMap.Put(value, key)\n}\n\n// Get searches the element in the map by key and returns its value or nil if key is not found in map.\n// Second return parameter is true if key was found, otherwise false.\nfunc (m *Map[K, V]) Get(key K) (value V, found bool) {\n\treturn m.forwardMap.Get(key)\n}\n\n// GetKey searches the element in the map by value and returns its key or nil if value is not found in map.\n// Second return parameter is true if value was found, otherwise false.\nfunc (m *Map[K, V]) GetKey(value V) (key K, found bool) {\n\treturn m.inverseMap.Get(value)\n}\n\n// Remove removes the element from the map by key.\nfunc (m *Map[K, V]) Remove(key K) {\n\tif v, found := m.forwardMap.Get(key); found {\n\t\tm.forwardMap.Remove(key)\n\t\tm.inverseMap.Remove(v)\n\t}\n}\n\n// Empty returns true if map does not contain any elements\nfunc (m *Map[K, V]) Empty() bool {\n\treturn m.Size() == 0\n}\n\n// Size returns number of elements in the map.\nfunc (m *Map[K, V]) Size() int {\n\treturn m.forwardMap.Size()\n}\n\n// Keys returns all keys (ordered).\nfunc (m *Map[K, V]) Keys() []K {\n\treturn m.forwardMap.Keys()\n}\n\n// Values returns all values (ordered).\nfunc (m *Map[K, V]) Values() []V {\n\treturn m.inverseMap.Keys()\n}\n\n// Clear removes all elements from the map.\nfunc (m *Map[K, V]) Clear() {\n\tm.forwardMap.Clear()\n\tm.inverseMap.Clear()\n}\n\n// String returns a string representation of container\nfunc (m *Map[K, V]) String() string {\n\tstr := \"TreeBidiMap\\nmap[\"\n\tit := m.Iterator()\n\tfor it.Next() {\n\t\tstr += fmt.Sprintf(\"%v:%v \", it.Key(), it.Value())\n\t}\n\treturn strings.TrimRight(str, \" \") + \"]\"\n}\n"
  },
  {
    "path": "maps/treebidimap/treebidimap_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treebidimap\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestMapPut(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tif actualValue := m.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4, 5, 6, 7})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"})\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestMapRemove(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tm.Remove(5)\n\tm.Remove(6)\n\tm.Remove(7)\n\tm.Remove(8)\n\tm.Remove(5)\n\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\"})\n\n\tif actualValue := m.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\tm.Remove(1)\n\tm.Remove(4)\n\tm.Remove(2)\n\tm.Remove(3)\n\tm.Remove(2)\n\tm.Remove(2)\n\n\ttestutils.SameElements(t, m.Keys(), nil)\n\ttestutils.SameElements(t, m.Values(), nil)\n\tif actualValue := m.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\tif actualValue := m.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestMapGetKey(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{0, \"x\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.GetKey(test[1].(string))\n\t\tif actualValue != test[0] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[0])\n\t\t}\n\t}\n}\n\nfunc sameElements(a []interface{}, b []interface{}) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor _, av := range a {\n\t\tfound := false\n\t\tfor _, bv := range b {\n\t\t\tif av == bv {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc TestMapEach(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tcount := 0\n\tm.Each(func(key string, value int) {\n\t\tcount++\n\t\tif actualValue, expectedValue := count, value; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tswitch value {\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := key, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := key, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 3:\n\t\t\tif actualValue, expectedValue := key, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestMapMap(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tmappedMap := m.Map(func(key1 string, value1 int) (key2 string, value2 int) {\n\t\treturn key1, value1 * value1\n\t})\n\tif actualValue, _ := mappedMap.Get(\"a\"); actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: a\")\n\t}\n\tif actualValue, _ := mappedMap.Get(\"b\"); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: b\")\n\t}\n\tif actualValue, _ := mappedMap.Get(\"c\"); actualValue != 9 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: c\")\n\t}\n\tif mappedMap.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedMap.Size(), 3)\n\t}\n}\n\nfunc TestMapSelect(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tselectedMap := m.Select(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"b\"\n\t})\n\tif actualValue, _ := selectedMap.Get(\"a\"); actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: a\")\n\t}\n\tif actualValue, _ := selectedMap.Get(\"b\"); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: b\")\n\t}\n\tif selectedMap.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedMap.Size(), 2)\n\t}\n}\n\nfunc TestMapAny(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tany := m.Any(func(key string, value int) bool {\n\t\treturn value == 3\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = m.Any(func(key string, value int) bool {\n\t\treturn value == 4\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\n\nfunc TestMapAll(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tall := m.All(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = m.All(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\n\nfunc TestMapFind(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tfoundKey, foundValue := m.Find(func(key string, value int) bool {\n\t\treturn key == \"c\"\n\t})\n\tif foundKey != \"c\" || foundValue != 3 {\n\t\tt.Errorf(\"Got %v -> %v expected %v -> %v\", foundKey, foundValue, \"c\", 3)\n\t}\n\tfoundKey, foundValue = m.Find(func(key string, value int) bool {\n\t\treturn key == \"x\"\n\t})\n\tif foundKey != \"\" || foundValue != 0 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundKey, nil, nil)\n\t}\n}\n\nfunc TestMapChaining(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tchainedMap := m.Select(func(key string, value int) bool {\n\t\treturn value > 1\n\t}).Map(func(key string, value int) (string, int) {\n\t\treturn key + key, value * value\n\t})\n\tif actualValue := chainedMap.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, found := chainedMap.Get(\"aa\"); actualValue != 0 || found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue, found := chainedMap.Get(\"bb\"); actualValue != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\tif actualValue, found := chainedMap.Get(\"cc\"); actualValue != 9 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 9)\n\t}\n}\n\nfunc TestMapIteratorNextOnEmpty(t *testing.T) {\n\tm := New[string, string]()\n\tit := m.Iterator()\n\tit = m.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t}\n}\n\nfunc TestMapIteratorPrevOnEmpty(t *testing.T) {\n\tm := New[string, string]()\n\tit := m.Iterator()\n\tit = m.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t}\n}\n\nfunc TestMapIteratorNext(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\n\tit := m.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tvalue := it.Value()\n\t\tswitch key {\n\t\tcase \"a\":\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"b\":\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"c\":\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapIteratorPrev(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\n\tit := m.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := m.Size()\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tvalue := it.Value()\n\t\tswitch key {\n\t\tcase \"a\":\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"b\":\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"c\":\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := value, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapIteratorBegin(t *testing.T) {\n\tm := New[int, string]()\n\tit := m.Iterator()\n\tit.Begin()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestMapIteratorEnd(t *testing.T) {\n\tm := New[int, string]()\n\tit := m.Iterator()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit.End()\n\tit.Prev()\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestMapIteratorFirst(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit := m.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestMapIteratorLast(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit := m.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestMapIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tm := New[int, string]()\n\t\tit := m.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"xx\")\n\t\tm.Put(1, \"yy\")\n\t\tit := m.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"aa\")\n\t\tm.Put(1, \"bb\")\n\t\tm.Put(2, \"cc\")\n\t\tit := m.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestMapIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tm := New[int, string]()\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"xx\")\n\t\tm.Put(1, \"yy\")\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"aa\")\n\t\tm.Put(1, \"bb\")\n\t\tm.Put(2, \"cc\")\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestMapSerialization(t *testing.T) {\n\tfor i := 0; i < 10; i++ {\n\t\toriginal := New[string, string]()\n\t\toriginal.Put(\"d\", \"4\")\n\t\toriginal.Put(\"e\", \"5\")\n\t\toriginal.Put(\"c\", \"3\")\n\t\toriginal.Put(\"b\", \"2\")\n\t\toriginal.Put(\"a\", \"1\")\n\n\t\tserialized, err := original.ToJSON()\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\n\t\tdeserialized := New[string, string]()\n\t\terr = deserialized.FromJSON(serialized)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\n\t\tif original.Size() != deserialized.Size() {\n\t\t\tt.Errorf(\"Got map of size %d, expected %d\", original.Size(), deserialized.Size())\n\t\t}\n\t\toriginal.Each(func(key string, expected string) {\n\t\t\tactual, ok := deserialized.Get(key)\n\t\t\tif !ok || actual != expected {\n\t\t\t\tt.Errorf(\"Did not find expected value %v for key %v in deserialied map (got %q)\", expected, key, actual)\n\t\t\t}\n\t\t})\n\t}\n\n\tm := New[string, float64]()\n\tm.Put(\"a\", 1.0)\n\tm.Put(\"b\", 2.0)\n\tm.Put(\"c\", 3.0)\n\n\t_, err := json.Marshal([]interface{}{\"a\", \"b\", \"c\", m})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), &m)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n}\n\nfunc TestMapString(t *testing.T) {\n\tc := New[string, string]()\n\tc.Put(\"a\", \"a\")\n\tif !strings.HasPrefix(c.String(), \"TreeBidiMap\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Put(n, n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, m *Map[int, int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkTreeBidiMapGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapPut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapPut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapPut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapPut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeBidiMapRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, int]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n"
  },
  {
    "path": "maps/treemap/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treemap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithKey[string, int] = (*Map[string, int])(nil)\n\n// Each calls the given function once for each element, passing that element's key and value.\nfunc (m *Map[K, V]) Each(f func(key K, value V)) {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Key(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a container\n// containing the values returned by the given function as key/value pairs.\nfunc (m *Map[K, V]) Map(f func(key1 K, value1 V) (K, V)) *Map[K, V] {\n\tnewMap := &Map[K, V]{tree: rbt.NewWith[K, V](m.tree.Comparator)}\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tkey2, value2 := f(iterator.Key(), iterator.Value())\n\t\tnewMap.Put(key2, value2)\n\t}\n\treturn newMap\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (m *Map[K, V]) Select(f func(key K, value V) bool) *Map[K, V] {\n\tnewMap := &Map[K, V]{tree: rbt.NewWith[K, V](m.tree.Comparator)}\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\tnewMap.Put(iterator.Key(), iterator.Value())\n\t\t}\n\t}\n\treturn newMap\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (m *Map[K, V]) Any(f func(key K, value V) bool) bool {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (m *Map[K, V]) All(f func(key K, value V) bool) bool {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Key(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (key,value) for which the function is true or nil,nil otherwise if no element\n// matches the criteria.\nfunc (m *Map[K, V]) Find(f func(key K, value V) bool) (k K, v V) {\n\titerator := m.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Key(), iterator.Value()) {\n\t\t\treturn iterator.Key(), iterator.Value()\n\t\t}\n\t}\n\treturn k, v\n}\n"
  },
  {
    "path": "maps/treemap/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treemap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithKey[string, int] = (*Iterator[string, int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[K comparable, V any] struct {\n\titerator *rbt.Iterator[K, V]\n}\n\n// Iterator returns a stateful iterator whose elements are key/value pairs.\nfunc (m *Map[K, V]) Iterator() *Iterator[K, V] {\n\treturn &Iterator[K, V]{iterator: m.tree.Iterator()}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Next() bool {\n\treturn iterator.iterator.Next()\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Prev() bool {\n\treturn iterator.iterator.Prev()\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Value() V {\n\treturn iterator.iterator.Value()\n}\n\n// Key returns the current element's key.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Key() K {\n\treturn iterator.iterator.Key()\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[K, V]) Begin() {\n\titerator.iterator.Begin()\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[K, V]) End() {\n\titerator.iterator.End()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator\nfunc (iterator *Iterator[K, V]) First() bool {\n\treturn iterator.iterator.First()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Last() bool {\n\treturn iterator.iterator.Last()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) NextTo(f func(key K, value V) bool) bool {\n\tfor iterator.Next() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) PrevTo(f func(key K, value V) bool) bool {\n\tfor iterator.Prev() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "maps/treemap/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treemap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Map[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Map[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the map.\nfunc (m *Map[K, V]) ToJSON() ([]byte, error) {\n\treturn m.tree.ToJSON()\n}\n\n// FromJSON populates the map from the input JSON representation.\nfunc (m *Map[K, V]) FromJSON(data []byte) error {\n\treturn m.tree.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (m *Map[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn m.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (m *Map[K, V]) MarshalJSON() ([]byte, error) {\n\treturn m.ToJSON()\n}\n"
  },
  {
    "path": "maps/treemap/treemap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package treemap implements a map backed by red-black tree.\n//\n// Elements are ordered by key in the map.\n//\n// Structure is not thread safe.\n//\n// Reference: http://en.wikipedia.org/wiki/Associative_array\npackage treemap\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/maps\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Map implementation\nvar _ maps.Map[string, int] = (*Map[string, int])(nil)\n\n// Map holds the elements in a red-black tree\ntype Map[K comparable, V any] struct {\n\ttree *rbt.Tree[K, V]\n}\n\n// New instantiates a tree map with the built-in comparator for K\nfunc New[K cmp.Ordered, V any]() *Map[K, V] {\n\treturn &Map[K, V]{tree: rbt.New[K, V]()}\n}\n\n// NewWith instantiates a tree map with the custom comparator.\nfunc NewWith[K comparable, V any](comparator utils.Comparator[K]) *Map[K, V] {\n\treturn &Map[K, V]{tree: rbt.NewWith[K, V](comparator)}\n}\n\n// Put inserts key-value pair into the map.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Put(key K, value V) {\n\tm.tree.Put(key, value)\n}\n\n// Get searches the element in the map by key and returns its value or nil if key is not found in tree.\n// Second return parameter is true if key was found, otherwise false.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Get(key K) (value V, found bool) {\n\treturn m.tree.Get(key)\n}\n\n// Remove removes the element from the map by key.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Remove(key K) {\n\tm.tree.Remove(key)\n}\n\n// Empty returns true if map does not contain any elements\nfunc (m *Map[K, V]) Empty() bool {\n\treturn m.tree.Empty()\n}\n\n// Size returns number of elements in the map.\nfunc (m *Map[K, V]) Size() int {\n\treturn m.tree.Size()\n}\n\n// Keys returns all keys in-order\nfunc (m *Map[K, V]) Keys() []K {\n\treturn m.tree.Keys()\n}\n\n// Values returns all values in-order based on the key.\nfunc (m *Map[K, V]) Values() []V {\n\treturn m.tree.Values()\n}\n\n// Clear removes all elements from the map.\nfunc (m *Map[K, V]) Clear() {\n\tm.tree.Clear()\n}\n\n// Min returns the minimum key and its value from the tree map.\n// Returns 0-value, 0-value, false if map is empty.\nfunc (m *Map[K, V]) Min() (key K, value V, ok bool) {\n\tif node := m.tree.Left(); node != nil {\n\t\treturn node.Key, node.Value, true\n\t}\n\treturn key, value, false\n}\n\n// Max returns the maximum key and its value from the tree map.\n// Returns 0-value, 0-value, false if map is empty.\nfunc (m *Map[K, V]) Max() (key K, value V, ok bool) {\n\tif node := m.tree.Right(); node != nil {\n\t\treturn node.Key, node.Value, true\n\t}\n\treturn key, value, false\n}\n\n// Floor finds the floor key-value pair for the input key.\n// In case that no floor is found, then both returned values will be nil.\n// It's generally enough to check the first value (key) for nil, which determines if floor was found.\n//\n// Floor key is defined as the largest key that is smaller than or equal to the given key.\n// A floor key may not be found, either because the map is empty, or because\n// all keys in the map are larger than the given key.\n//\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Floor(key K) (foundKey K, foundValue V, ok bool) {\n\tnode, found := m.tree.Floor(key)\n\tif found {\n\t\treturn node.Key, node.Value, true\n\t}\n\treturn foundKey, foundValue, false\n}\n\n// Ceiling finds the ceiling key-value pair for the input key.\n// In case that no ceiling is found, then both returned values will be nil.\n// It's generally enough to check the first value (key) for nil, which determines if ceiling was found.\n//\n// Ceiling key is defined as the smallest key that is larger than or equal to the given key.\n// A ceiling key may not be found, either because the map is empty, or because\n// all keys in the map are smaller than the given key.\n//\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (m *Map[K, V]) Ceiling(key K) (foundKey K, foundValue V, ok bool) {\n\tnode, found := m.tree.Ceiling(key)\n\tif found {\n\t\treturn node.Key, node.Value, true\n\t}\n\treturn foundKey, foundValue, false\n}\n\n// String returns a string representation of container\nfunc (m *Map[K, V]) String() string {\n\tstr := \"TreeMap\\nmap[\"\n\tit := m.Iterator()\n\tfor it.Next() {\n\t\tstr += fmt.Sprintf(\"%v:%v \", it.Key(), it.Value())\n\t}\n\treturn strings.TrimRight(str, \" \") + \"]\"\n\n}\n"
  },
  {
    "path": "maps/treemap/treemap_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treemap\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestMapPut(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tif actualValue := m.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4, 5, 6, 7})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"})\n\n\t// key,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestMapMin(t *testing.T) {\n\tm := New[int, string]()\n\n\tif k, v, ok := m.Min(); k != 0 || v != \"\" || ok {\n\t\tt.Errorf(\"Got %v->%v->%v expected %v->%v-%v\", k, v, ok, 0, \"\", false)\n\t}\n\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tactualKey, actualValue, actualOk := m.Min()\n\texpectedKey, expectedValue, expectedOk := 1, \"a\", true\n\tif actualKey != expectedKey {\n\t\tt.Errorf(\"Got %v expected %v\", actualKey, expectedKey)\n\t}\n\tif actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualOk != expectedOk {\n\t\tt.Errorf(\"Got %v expected %v\", actualOk, expectedOk)\n\t}\n}\n\nfunc TestMapMax(t *testing.T) {\n\tm := New[int, string]()\n\n\tif k, v, ok := m.Max(); k != 0 || v != \"\" || ok {\n\t\tt.Errorf(\"Got %v->%v->%v expected %v->%v-%v\", k, v, ok, 0, \"\", false)\n\t}\n\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tactualKey, actualValue, actualOk := m.Max()\n\texpectedKey, expectedValue, expectedOk := 7, \"g\", true\n\tif actualKey != expectedKey {\n\t\tt.Errorf(\"Got %v expected %v\", actualKey, expectedKey)\n\t}\n\tif actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualOk != expectedOk {\n\t\tt.Errorf(\"Got %v expected %v\", actualOk, expectedOk)\n\t}\n}\n\nfunc TestMapClear(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tif actualValue, expectedValue := m.Size(), 4; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tm.Clear()\n\tif actualValue, expectedValue := m.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapRemove(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(5, \"e\")\n\tm.Put(6, \"f\")\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(4, \"d\")\n\tm.Put(1, \"x\")\n\tm.Put(2, \"b\")\n\tm.Put(1, \"a\") //overwrite\n\n\tm.Remove(5)\n\tm.Remove(6)\n\tm.Remove(7)\n\tm.Remove(8)\n\tm.Remove(5)\n\n\ttestutils.SameElements(t, m.Keys(), []int{1, 2, 3, 4})\n\ttestutils.SameElements(t, m.Values(), []string{\"a\", \"b\", \"c\", \"d\"})\n\n\tif actualValue := m.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := m.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\tm.Remove(1)\n\tm.Remove(4)\n\tm.Remove(2)\n\tm.Remove(3)\n\tm.Remove(2)\n\tm.Remove(2)\n\n\ttestutils.SameElements(t, m.Keys(), nil)\n\ttestutils.SameElements(t, m.Values(), nil)\n\tif actualValue := m.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\tif actualValue := m.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestMapFloor(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\n\t// key,expectedKey,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{-1, 0, \"\", false},\n\t\t{0, 0, \"\", false},\n\t\t{1, 1, \"a\", true},\n\t\t{2, 1, \"a\", true},\n\t\t{3, 3, \"c\", true},\n\t\t{4, 3, \"c\", true},\n\t\t{7, 7, \"g\", true},\n\t\t{8, 7, \"g\", true},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualKey, actualValue, actualOk := m.Floor(test[0].(int))\n\t\tif actualKey != test[1] || actualValue != test[2] || actualOk != test[3] {\n\t\t\tt.Errorf(\"Got %v, %v, %v, expected %v, %v, %v\", actualKey, actualValue, actualOk, test[1], test[2], test[3])\n\t\t}\n\t}\n}\n\nfunc TestMapCeiling(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(7, \"g\")\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\n\t// key,expectedKey,expectedValue,expectedFound\n\ttests1 := [][]interface{}{\n\t\t{-1, 1, \"a\", true},\n\t\t{0, 1, \"a\", true},\n\t\t{1, 1, \"a\", true},\n\t\t{2, 3, \"c\", true},\n\t\t{3, 3, \"c\", true},\n\t\t{4, 7, \"g\", true},\n\t\t{7, 7, \"g\", true},\n\t\t{8, 0, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualKey, actualValue, actualOk := m.Ceiling(test[0].(int))\n\t\tif actualKey != test[1] || actualValue != test[2] || actualOk != test[3] {\n\t\t\tt.Errorf(\"Got %v, %v, %v, expected %v, %v, %v\", actualKey, actualValue, actualOk, test[1], test[2], test[3])\n\t\t}\n\t}\n}\n\nfunc TestMapEach(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tcount := 0\n\tm.Each(func(key string, value int) {\n\t\tcount++\n\t\tif actualValue, expectedValue := count, value; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tswitch value {\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := key, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := key, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 3:\n\t\t\tif actualValue, expectedValue := key, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestMapMap(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tmappedMap := m.Map(func(key1 string, value1 int) (key2 string, value2 int) {\n\t\treturn key1, value1 * value1\n\t})\n\tif actualValue, _ := mappedMap.Get(\"a\"); actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: a\")\n\t}\n\tif actualValue, _ := mappedMap.Get(\"b\"); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: b\")\n\t}\n\tif actualValue, _ := mappedMap.Get(\"c\"); actualValue != 9 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"mapped: c\")\n\t}\n\tif mappedMap.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedMap.Size(), 3)\n\t}\n}\n\nfunc TestMapSelect(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tselectedMap := m.Select(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"b\"\n\t})\n\tif actualValue, _ := selectedMap.Get(\"a\"); actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: a\")\n\t}\n\tif actualValue, _ := selectedMap.Get(\"b\"); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"value: b\")\n\t}\n\tif selectedMap.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedMap.Size(), 2)\n\t}\n}\n\nfunc TestMapAny(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tany := m.Any(func(key string, value int) bool {\n\t\treturn value == 3\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = m.Any(func(key string, value int) bool {\n\t\treturn value == 4\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\n\nfunc TestMapAll(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tall := m.All(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = m.All(func(key string, value int) bool {\n\t\treturn key >= \"a\" && key <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\n\nfunc TestMapFind(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tfoundKey, foundValue := m.Find(func(key string, value int) bool {\n\t\treturn key == \"c\"\n\t})\n\tif foundKey != \"c\" || foundValue != 3 {\n\t\tt.Errorf(\"Got %v -> %v expected %v -> %v\", foundKey, foundValue, \"c\", 3)\n\t}\n\tfoundKey, foundValue = m.Find(func(key string, value int) bool {\n\t\treturn key == \"x\"\n\t})\n\tif foundKey != \"\" || foundValue != 0 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundKey, nil, nil)\n\t}\n}\n\nfunc TestMapChaining(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\tchainedMap := m.Select(func(key string, value int) bool {\n\t\treturn value > 1\n\t}).Map(func(key string, value int) (string, int) {\n\t\treturn key + key, value * value\n\t})\n\tif actualValue := chainedMap.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, found := chainedMap.Get(\"aa\"); actualValue != 0 || found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue, found := chainedMap.Get(\"bb\"); actualValue != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\tif actualValue, found := chainedMap.Get(\"cc\"); actualValue != 9 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 9)\n\t}\n}\n\nfunc TestMapIteratorNextOnEmpty(t *testing.T) {\n\tm := New[string, int]()\n\tit := m.Iterator()\n\tit = m.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t}\n}\n\nfunc TestMapIteratorPrevOnEmpty(t *testing.T) {\n\tm := New[string, int]()\n\tit := m.Iterator()\n\tit = m.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t}\n}\n\nfunc TestMapIteratorNext(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\n\tit := m.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tvalue := it.Value()\n\t\tswitch key {\n\t\tcase \"a\":\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"b\":\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"c\":\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapIteratorPrev(t *testing.T) {\n\tm := New[string, int]()\n\tm.Put(\"c\", 3)\n\tm.Put(\"a\", 1)\n\tm.Put(\"b\", 2)\n\n\tit := m.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := m.Size()\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tvalue := it.Value()\n\t\tswitch key {\n\t\tcase \"a\":\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"b\":\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase \"c\":\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := value, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestMapIteratorBegin(t *testing.T) {\n\tm := New[int, string]()\n\tit := m.Iterator()\n\tit.Begin()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestMapIteratorEnd(t *testing.T) {\n\tm := New[int, string]()\n\tit := m.Iterator()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit.End()\n\tit.Prev()\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestMapIteratorFirst(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit := m.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestMapIteratorLast(t *testing.T) {\n\tm := New[int, string]()\n\tm.Put(3, \"c\")\n\tm.Put(1, \"a\")\n\tm.Put(2, \"b\")\n\tit := m.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestMapIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tm := New[int, string]()\n\t\tit := m.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"xx\")\n\t\tm.Put(1, \"yy\")\n\t\tit := m.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"aa\")\n\t\tm.Put(1, \"bb\")\n\t\tm.Put(2, \"cc\")\n\t\tit := m.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestMapIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tm := New[int, string]()\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"xx\")\n\t\tm.Put(1, \"yy\")\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tm := New[int, string]()\n\t\tm.Put(0, \"aa\")\n\t\tm.Put(1, \"bb\")\n\t\tm.Put(2, \"cc\")\n\t\tit := m.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty map\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestMapSerialization(t *testing.T) {\n\tfor i := 0; i < 10; i++ {\n\t\toriginal := New[string, string]()\n\t\toriginal.Put(\"d\", \"4\")\n\t\toriginal.Put(\"e\", \"5\")\n\t\toriginal.Put(\"c\", \"3\")\n\t\toriginal.Put(\"b\", \"2\")\n\t\toriginal.Put(\"a\", \"1\")\n\n\t\tassertSerialization(original, \"A\", t)\n\n\t\tserialized, err := original.ToJSON()\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t\tassertSerialization(original, \"B\", t)\n\n\t\tdeserialized := New[string, string]()\n\t\terr = deserialized.FromJSON(serialized)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t\tassertSerialization(deserialized, \"C\", t)\n\t}\n\n\tm := New[string, float64]()\n\tm.Put(\"a\", 1.0)\n\tm.Put(\"b\", 2.0)\n\tm.Put(\"c\", 3.0)\n\n\t_, err := json.Marshal([]interface{}{\"a\", \"b\", \"c\", m})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), &m)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n}\n\nfunc TestMapString(t *testing.T) {\n\tc := New[string, int]()\n\tc.Put(\"a\", 1)\n\tif !strings.HasPrefix(c.String(), \"TreeMap\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\n// noinspection GoBoolExpressions\nfunc assertSerialization(m *Map[string, string], txt string, t *testing.T) {\n\tif actualValue := m.Keys(); false ||\n\t\tactualValue[0] != \"a\" ||\n\t\tactualValue[1] != \"b\" ||\n\t\tactualValue[2] != \"c\" ||\n\t\tactualValue[3] != \"d\" ||\n\t\tactualValue[4] != \"e\" {\n\t\tt.Errorf(\"[%s] Got %v expected %v\", txt, actualValue, \"[a,b,c,d,e]\")\n\t}\n\tif actualValue := m.Values(); false ||\n\t\tactualValue[0] != \"1\" ||\n\t\tactualValue[1] != \"2\" ||\n\t\tactualValue[2] != \"3\" ||\n\t\tactualValue[3] != \"4\" ||\n\t\tactualValue[4] != \"5\" {\n\t\tt.Errorf(\"[%s] Got %v expected %v\", txt, actualValue, \"[1,2,3,4,5]\")\n\t}\n\tif actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue {\n\t\tt.Errorf(\"[%s] Got %v expected %v\", txt, actualValue, expectedValue)\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, m *Map[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, m *Map[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Put(n, struct{}{})\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, m *Map[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tm.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkTreeMapGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, struct{}]()\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapPut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n\nfunc BenchmarkTreeMapRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tm := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\tm.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, m, size)\n}\n"
  },
  {
    "path": "queues/arrayqueue/arrayqueue.go",
    "content": "// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package arrayqueue implements a queue backed by array list.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/Queue_(abstract_data_type)\npackage arrayqueue\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/arraylist\"\n\t\"github.com/emirpasic/gods/v2/queues\"\n)\n\n// Assert Queue implementation\nvar _ queues.Queue[int] = (*Queue[int])(nil)\n\n// Queue holds elements in an array-list\ntype Queue[T comparable] struct {\n\tlist *arraylist.List[T]\n}\n\n// New instantiates a new empty queue\nfunc New[T comparable]() *Queue[T] {\n\treturn &Queue[T]{list: arraylist.New[T]()}\n}\n\n// Enqueue adds a value to the end of the queue\nfunc (queue *Queue[T]) Enqueue(value T) {\n\tqueue.list.Add(value)\n}\n\n// Dequeue removes first element of the queue and returns it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to dequeue.\nfunc (queue *Queue[T]) Dequeue() (value T, ok bool) {\n\tvalue, ok = queue.list.Get(0)\n\tif ok {\n\t\tqueue.list.Remove(0)\n\t}\n\treturn\n}\n\n// Peek returns first element of the queue without removing it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to peek.\nfunc (queue *Queue[T]) Peek() (value T, ok bool) {\n\treturn queue.list.Get(0)\n}\n\n// Empty returns true if queue does not contain any elements.\nfunc (queue *Queue[T]) Empty() bool {\n\treturn queue.list.Empty()\n}\n\n// Size returns number of elements within the queue.\nfunc (queue *Queue[T]) Size() int {\n\treturn queue.list.Size()\n}\n\n// Clear removes all elements from the queue.\nfunc (queue *Queue[T]) Clear() {\n\tqueue.list.Clear()\n}\n\n// Values returns all elements in the queue (FIFO order).\nfunc (queue *Queue[T]) Values() []T {\n\treturn queue.list.Values()\n}\n\n// String returns a string representation of container\nfunc (queue *Queue[T]) String() string {\n\tstr := \"ArrayQueue\\n\"\n\tvalues := []string{}\n\tfor _, value := range queue.list.Values() {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (queue *Queue[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < queue.list.Size()\n}\n"
  },
  {
    "path": "queues/arrayqueue/arrayqueue_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arrayqueue\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestQueueEnqueue(t *testing.T) {\n\tqueue := New[int]()\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\n\tif actualValue := queue.Values(); actualValue[0] != 1 || actualValue[1] != 2 || actualValue[2] != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[1,2,3]\")\n\t}\n\tif actualValue := queue.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := queue.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestQueuePeek(t *testing.T) {\n\tqueue := New[int]()\n\tif actualValue, ok := queue.Peek(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestQueueDequeue(t *testing.T) {\n\tqueue := New[int]()\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tqueue.Dequeue()\n\tif actualValue, ok := queue.Peek(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := queue.Values(); len(actualValue) != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[]\")\n\t}\n}\n\nfunc TestQueueIteratorOnEmpty(t *testing.T) {\n\tqueue := New[int]()\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestQueueIteratorNext(t *testing.T) {\n\tqueue := New[string]()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tit := queue.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tqueue.Clear()\n\tit = queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestQueueIteratorPrev(t *testing.T) {\n\tqueue := New[string]()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, 3-count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestQueueIteratorBegin(t *testing.T) {\n\tqueue := New[string]()\n\tit := queue.Iterator()\n\tit.Begin()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestQueueIteratorEnd(t *testing.T) {\n\tqueue := New[string]()\n\tit := queue.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tit.End()\n\tif index := it.Index(); index != queue.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, queue.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != queue.Size()-1 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, queue.Size()-1, \"c\")\n\t}\n}\n\nfunc TestQueueIteratorFirst(t *testing.T) {\n\tqueue := New[string]()\n\tit := queue.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestQueueIteratorLast(t *testing.T) {\n\tqueue := New[string]()\n\tit := queue.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"c\")\n\t}\n}\n\nfunc TestQueueIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tqueue := New[string]()\n\t\tit := queue.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tqueue := New[string]()\n\t\tqueue.Enqueue(\"xx\")\n\t\tqueue.Enqueue(\"yy\")\n\t\tit := queue.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tqueue := New[string]()\n\t\tqueue.Enqueue(\"aa\")\n\t\tqueue.Enqueue(\"bb\")\n\t\tqueue.Enqueue(\"cc\")\n\t\tit := queue.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestQueueIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tqueue := New[string]()\n\t\tit := queue.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tqueue := New[string]()\n\t\tqueue.Enqueue(\"xx\")\n\t\tqueue.Enqueue(\"yy\")\n\t\tit := queue.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tqueue := New[string]()\n\t\tqueue.Enqueue(\"aa\")\n\t\tqueue.Enqueue(\"bb\")\n\t\tqueue.Enqueue(\"cc\")\n\t\tit := queue.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestQueueSerialization(t *testing.T) {\n\tqueue := New[string]()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, queue.Values(), []string{\"a\", \"b\", \"c\"})\n\t\tif actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := queue.ToJSON()\n\tassert()\n\n\terr = queue.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", queue})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &queue)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestQueueString(t *testing.T) {\n\tc := New[int]()\n\tc.Enqueue(1)\n\tif !strings.HasPrefix(c.String(), \"ArrayQueue\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkEnqueue(b *testing.B, queue *Queue[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Enqueue(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkDequeue(b *testing.B, queue *Queue[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Dequeue()\n\t\t}\n\t}\n}\n\nfunc BenchmarkArrayQueueDequeue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := New[int]()\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n"
  },
  {
    "path": "queues/arrayqueue/iterator.go",
    "content": "// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arrayqueue\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\tqueue *Queue[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (queue *Queue[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{queue: queue, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.queue.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.queue.withinRange(iterator.index)\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\treturn iterator.queue.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\tvalue, _ := iterator.queue.list.Get(iterator.index)\n\treturn value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.queue.Size()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "queues/arrayqueue/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arrayqueue\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Queue[int])(nil)\nvar _ containers.JSONDeserializer = (*Queue[int])(nil)\n\n// ToJSON outputs the JSON representation of the queue.\nfunc (queue *Queue[T]) ToJSON() ([]byte, error) {\n\treturn queue.list.ToJSON()\n}\n\n// FromJSON populates the queue from the input JSON representation.\nfunc (queue *Queue[T]) FromJSON(data []byte) error {\n\treturn queue.list.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (queue *Queue[T]) UnmarshalJSON(bytes []byte) error {\n\treturn queue.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (queue *Queue[T]) MarshalJSON() ([]byte, error) {\n\treturn queue.ToJSON()\n}\n"
  },
  {
    "path": "queues/circularbuffer/circularbuffer.go",
    "content": "// Copyright (c) 2021, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package circularbuffer implements the circular buffer.\n//\n// In computer science, a circular buffer, circular queue, cyclic buffer or ring buffer is a data structure that uses a single, fixed-size buffer as if it were connected end-to-end. This structure lends itself easily to buffering data streams.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/Circular_buffer\npackage circularbuffer\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/queues\"\n)\n\n// Assert Queue implementation\nvar _ queues.Queue[int] = (*Queue[int])(nil)\n\n// Queue holds values in a slice.\ntype Queue[T comparable] struct {\n\tvalues  []T\n\tstart   int\n\tend     int\n\tfull    bool\n\tmaxSize int\n\tsize    int\n}\n\n// New instantiates a new empty queue with the specified size of maximum number of elements that it can hold.\n// This max size of the buffer cannot be changed.\nfunc New[T comparable](maxSize int) *Queue[T] {\n\tif maxSize < 1 {\n\t\tpanic(\"Invalid maxSize, should be at least 1\")\n\t}\n\tqueue := &Queue[T]{maxSize: maxSize}\n\tqueue.Clear()\n\treturn queue\n}\n\n// Enqueue adds a value to the end of the queue\nfunc (queue *Queue[T]) Enqueue(value T) {\n\tif queue.Full() {\n\t\tqueue.Dequeue()\n\t}\n\tqueue.values[queue.end] = value\n\tqueue.end = queue.end + 1\n\tif queue.end >= queue.maxSize {\n\t\tqueue.end = 0\n\t}\n\tif queue.end == queue.start {\n\t\tqueue.full = true\n\t}\n\n\tqueue.size = queue.calculateSize()\n}\n\n// Dequeue removes first element of the queue and returns it, or the 0-value if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to dequeue.\nfunc (queue *Queue[T]) Dequeue() (value T, ok bool) {\n\tif queue.Empty() {\n\t\treturn value, false\n\t}\n\n\tvalue, ok = queue.values[queue.start], true\n\tqueue.start = queue.start + 1\n\tif queue.start >= queue.maxSize {\n\t\tqueue.start = 0\n\t}\n\tqueue.full = false\n\tqueue.size = queue.size - 1\n\n\treturn\n}\n\n// Peek returns first element of the queue without removing it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to peek.\nfunc (queue *Queue[T]) Peek() (value T, ok bool) {\n\tif queue.Empty() {\n\t\treturn value, false\n\t}\n\treturn queue.values[queue.start], true\n}\n\n// Empty returns true if queue does not contain any elements.\nfunc (queue *Queue[T]) Empty() bool {\n\treturn queue.Size() == 0\n}\n\n// Full returns true if the queue is full, i.e. has reached the maximum number of elements that it can hold.\nfunc (queue *Queue[T]) Full() bool {\n\treturn queue.Size() == queue.maxSize\n}\n\n// Size returns number of elements within the queue.\nfunc (queue *Queue[T]) Size() int {\n\treturn queue.size\n}\n\n// Clear removes all elements from the queue.\nfunc (queue *Queue[T]) Clear() {\n\tqueue.values = make([]T, queue.maxSize, queue.maxSize)\n\tqueue.start = 0\n\tqueue.end = 0\n\tqueue.full = false\n\tqueue.size = 0\n}\n\n// Values returns all elements in the queue (FIFO order).\nfunc (queue *Queue[T]) Values() []T {\n\tvalues := make([]T, queue.Size(), queue.Size())\n\tfor i := 0; i < queue.Size(); i++ {\n\t\tvalues[i] = queue.values[(queue.start+i)%queue.maxSize]\n\t}\n\treturn values\n}\n\n// String returns a string representation of container\nfunc (queue *Queue[T]) String() string {\n\tstr := \"CircularBuffer\\n\"\n\tvar values []string\n\tfor _, value := range queue.Values() {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (queue *Queue[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < queue.size\n}\n\nfunc (queue *Queue[T]) calculateSize() int {\n\tif queue.end < queue.start {\n\t\treturn queue.maxSize - queue.start + queue.end\n\t} else if queue.end == queue.start {\n\t\tif queue.full {\n\t\t\treturn queue.maxSize\n\t\t}\n\t\treturn 0\n\t}\n\treturn queue.end - queue.start\n}\n"
  },
  {
    "path": "queues/circularbuffer/circularbuffer_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage circularbuffer\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestQueueEnqueue(t *testing.T) {\n\tqueue := New[int](3)\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\n\tif actualValue := queue.Values(); actualValue[0] != 1 || actualValue[1] != 2 || actualValue[2] != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[1,2,3]\")\n\t}\n\tif actualValue := queue.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := queue.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestQueuePeek(t *testing.T) {\n\tqueue := New[int](3)\n\tif actualValue, ok := queue.Peek(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestQueueDequeue(t *testing.T) {\n\tassert := func(actualValue interface{}, expectedValue interface{}) {\n\t\tif actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\n\tqueue := New[int](3)\n\tassert(queue.Empty(), true)\n\tassert(queue.Empty(), true)\n\tassert(queue.Full(), false)\n\tassert(queue.Size(), 0)\n\tqueue.Enqueue(1)\n\tassert(queue.Size(), 1)\n\tqueue.Enqueue(2)\n\tassert(queue.Size(), 2)\n\n\tqueue.Enqueue(3)\n\tassert(queue.Size(), 3)\n\tassert(queue.Empty(), false)\n\tassert(queue.Full(), true)\n\n\tqueue.Dequeue()\n\tassert(queue.Size(), 2)\n\n\tif actualValue, ok := queue.Peek(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tassert(queue.Size(), 2)\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tassert(queue.Size(), 1)\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tassert(queue.Size(), 0)\n\tassert(queue.Empty(), true)\n\tassert(queue.Full(), false)\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tassert(queue.Size(), 0)\n\n\tassert(queue.Empty(), true)\n\tassert(queue.Full(), false)\n\tassert(len(queue.Values()), 0)\n}\n\nfunc TestQueueDequeueFull(t *testing.T) {\n\tassert := func(actualValue interface{}, expectedValue interface{}) {\n\t\tif actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\n\tqueue := New[int](2)\n\tassert(queue.Empty(), true)\n\tassert(queue.Full(), false)\n\tassert(queue.Size(), 0)\n\n\tqueue.Enqueue(1)\n\tassert(queue.Size(), 1)\n\n\tqueue.Enqueue(2)\n\tassert(queue.Size(), 2)\n\tassert(queue.Full(), true)\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tqueue.Enqueue(3) // overwrites 1\n\tassert(queue.Size(), 2)\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, expectedValue := queue.Size(), 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tif actualValue, ok := queue.Peek(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, expectedValue := queue.Size(), 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tassert(queue.Size(), 0)\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tassert(queue.Empty(), true)\n\tassert(queue.Full(), false)\n\tassert(len(queue.Values()), 0)\n}\n\nfunc TestQueueIteratorOnEmpty(t *testing.T) {\n\tqueue := New[int](3)\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestQueueIteratorNext(t *testing.T) {\n\tqueue := New[string](3)\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tit := queue.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tqueue.Clear()\n\tit = queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestQueueIteratorPrev(t *testing.T) {\n\tqueue := New[string](3)\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, 3-count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestQueueIteratorBegin(t *testing.T) {\n\tqueue := New[string](3)\n\tit := queue.Iterator()\n\tit.Begin()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestQueueIteratorEnd(t *testing.T) {\n\tqueue := New[string](3)\n\tit := queue.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tit.End()\n\tif index := it.Index(); index != queue.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, queue.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != queue.Size()-1 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, queue.Size()-1, \"c\")\n\t}\n}\n\nfunc TestQueueIteratorFirst(t *testing.T) {\n\tqueue := New[string](3)\n\tit := queue.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestQueueIteratorLast(t *testing.T) {\n\tqueue := New[string](3)\n\tit := queue.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"c\")\n\t}\n}\n\nfunc TestQueueIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tqueue := New[string](3)\n\t\tit := queue.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tqueue := New[string](3)\n\t\tqueue.Enqueue(\"xx\")\n\t\tqueue.Enqueue(\"yy\")\n\t\tit := queue.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tqueue := New[string](3)\n\t\tqueue.Enqueue(\"aa\")\n\t\tqueue.Enqueue(\"bb\")\n\t\tqueue.Enqueue(\"cc\")\n\t\tit := queue.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestQueueIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tqueue := New[string](3)\n\t\tit := queue.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tqueue := New[string](3)\n\t\tqueue.Enqueue(\"xx\")\n\t\tqueue.Enqueue(\"yy\")\n\t\tit := queue.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tqueue := New[string](3)\n\t\tqueue.Enqueue(\"aa\")\n\t\tqueue.Enqueue(\"bb\")\n\t\tqueue.Enqueue(\"cc\")\n\t\tit := queue.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestQueueIterator(t *testing.T) {\n\tassert := func(actualValue interface{}, expectedValue interface{}) {\n\t\tif actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\n\tqueue := New[string](2)\n\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\") // overwrites \"a\"\n\n\tit := queue.Iterator()\n\n\tif actualIndex, expectedIndex := it.Index(), -1; actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", actualIndex, expectedIndex)\n\t}\n\n\tassert(it.Next(), true)\n\n\tif actualValue, actualIndex, expectedValue, expectedIndex := it.Value(), it.Index(), \"b\", 0; actualValue != expectedValue || actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v, Got %v expected %v\", actualValue, expectedValue, actualIndex, expectedIndex)\n\t}\n\n\tassert(it.Next(), true)\n\n\tif actualValue, actualIndex, expectedValue, expectedIndex := it.Value(), it.Index(), \"c\", 1; actualValue != expectedValue || actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v, Got %v expected %v\", actualValue, expectedValue, actualIndex, expectedIndex)\n\t}\n\n\tassert(it.Next(), false)\n\n\tif actualIndex, expectedIndex := it.Index(), 2; actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", actualIndex, expectedIndex)\n\t}\n\n\tassert(it.Next(), false)\n\n\tassert(it.Prev(), true)\n\n\tif actualValue, actualIndex, expectedValue, expectedIndex := it.Value(), it.Index(), \"c\", 1; actualValue != expectedValue || actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v, Got %v expected %v\", actualValue, expectedValue, actualIndex, expectedIndex)\n\t}\n\n\tassert(it.Prev(), true)\n\n\tif actualValue, actualIndex, expectedValue, expectedIndex := it.Value(), it.Index(), \"b\", 0; actualValue != expectedValue || actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v, Got %v expected %v\", actualValue, expectedValue, actualIndex, expectedIndex)\n\t}\n\n\tassert(it.Prev(), false)\n\n\tif actualIndex, expectedIndex := it.Index(), -1; actualIndex != expectedIndex {\n\t\tt.Errorf(\"Got %v expected %v\", actualIndex, expectedIndex)\n\t}\n}\n\nfunc TestQueueSerialization(t *testing.T) {\n\tqueue := New[string](3)\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, queue.Values(), []string{\"a\", \"b\", \"c\"})\n\t\tif actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := queue.ToJSON()\n\tassert()\n\n\terr = queue.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", queue})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &queue)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestQueueString(t *testing.T) {\n\tc := New[int](3)\n\tc.Enqueue(1)\n\tif !strings.HasPrefix(c.String(), \"CircularBuffer\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkEnqueue(b *testing.B, queue *Queue[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Enqueue(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkDequeue(b *testing.B, queue *Queue[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Dequeue()\n\t\t}\n\t}\n}\n\nfunc BenchmarkArrayQueueDequeue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := New[int](3)\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := New[int](3)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n"
  },
  {
    "path": "queues/circularbuffer/iterator.go",
    "content": "// Copyright (c) 2021, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage circularbuffer\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\tqueue *Queue[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (queue *Queue[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{queue: queue, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.queue.size {\n\t\titerator.index++\n\t}\n\treturn iterator.queue.withinRange(iterator.index)\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\treturn iterator.queue.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\tindex := (iterator.index + iterator.queue.start) % iterator.queue.maxSize\n\tvalue := iterator.queue.values[index]\n\treturn value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.queue.size\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "queues/circularbuffer/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage circularbuffer\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Queue[int])(nil)\nvar _ containers.JSONDeserializer = (*Queue[int])(nil)\n\n// ToJSON outputs the JSON representation of queue's elements.\nfunc (queue *Queue[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(queue.values[:queue.maxSize])\n}\n\n// FromJSON populates list's elements from the input JSON representation.\nfunc (queue *Queue[T]) FromJSON(data []byte) error {\n\tvar values []T\n\terr := json.Unmarshal(data, &values)\n\tif err == nil {\n\t\tfor _, value := range values {\n\t\t\tqueue.Enqueue(value)\n\t\t}\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (queue *Queue[T]) UnmarshalJSON(bytes []byte) error {\n\treturn queue.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (queue *Queue[T]) MarshalJSON() ([]byte, error) {\n\treturn queue.ToJSON()\n}\n"
  },
  {
    "path": "queues/linkedlistqueue/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedlistqueue\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.IteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\tqueue *Queue[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (queue *Queue[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{queue: queue, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.queue.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.queue.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\tvalue, _ := iterator.queue.list.Get(iterator.index)\n\treturn value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "queues/linkedlistqueue/linkedlistqueue.go",
    "content": "// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package linkedlistqueue implements a queue backed by a singly-linked list.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/Queue_(abstract_data_type)\npackage linkedlistqueue\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/singlylinkedlist\"\n\t\"github.com/emirpasic/gods/v2/queues\"\n)\n\n// Assert Queue implementation\nvar _ queues.Queue[int] = (*Queue[int])(nil)\n\n// Queue holds elements in a singly-linked-list\ntype Queue[T comparable] struct {\n\tlist *singlylinkedlist.List[T]\n}\n\n// New instantiates a new empty queue\nfunc New[T comparable]() *Queue[T] {\n\treturn &Queue[T]{list: singlylinkedlist.New[T]()}\n}\n\n// Enqueue adds a value to the end of the queue\nfunc (queue *Queue[T]) Enqueue(value T) {\n\tqueue.list.Add(value)\n}\n\n// Dequeue removes first element of the queue and returns it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to dequeue.\nfunc (queue *Queue[T]) Dequeue() (value T, ok bool) {\n\tvalue, ok = queue.list.Get(0)\n\tif ok {\n\t\tqueue.list.Remove(0)\n\t}\n\treturn\n}\n\n// Peek returns first element of the queue without removing it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to peek.\nfunc (queue *Queue[T]) Peek() (value T, ok bool) {\n\treturn queue.list.Get(0)\n}\n\n// Empty returns true if queue does not contain any elements.\nfunc (queue *Queue[T]) Empty() bool {\n\treturn queue.list.Empty()\n}\n\n// Size returns number of elements within the queue.\nfunc (queue *Queue[T]) Size() int {\n\treturn queue.list.Size()\n}\n\n// Clear removes all elements from the queue.\nfunc (queue *Queue[T]) Clear() {\n\tqueue.list.Clear()\n}\n\n// Values returns all elements in the queue (FIFO order).\nfunc (queue *Queue[T]) Values() []T {\n\treturn queue.list.Values()\n}\n\n// String returns a string representation of container\nfunc (queue *Queue[T]) String() string {\n\tstr := \"LinkedListQueue\\n\"\n\tvalues := []string{}\n\tfor _, value := range queue.list.Values() {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (queue *Queue[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < queue.list.Size()\n}\n"
  },
  {
    "path": "queues/linkedlistqueue/linkedlistqueue_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedlistqueue\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestQueueEnqueue(t *testing.T) {\n\tqueue := New[int]()\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\n\tif actualValue := queue.Values(); actualValue[0] != 1 || actualValue[1] != 2 || actualValue[2] != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[1,2,3]\")\n\t}\n\tif actualValue := queue.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := queue.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestQueuePeek(t *testing.T) {\n\tqueue := New[int]()\n\tif actualValue, ok := queue.Peek(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tif actualValue, ok := queue.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestQueueDequeue(t *testing.T) {\n\tqueue := New[int]()\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tqueue.Dequeue()\n\tif actualValue, ok := queue.Peek(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := queue.Values(); len(actualValue) != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[]\")\n\t}\n}\n\nfunc TestQueueIteratorOnEmpty(t *testing.T) {\n\tqueue := New[int]()\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestQueueIteratorNext(t *testing.T) {\n\tqueue := New[string]()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tit := queue.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tqueue.Clear()\n\tit = queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestQueueIteratorBegin(t *testing.T) {\n\tqueue := New[string]()\n\tit := queue.Iterator()\n\tit.Begin()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestQueueIteratorFirst(t *testing.T) {\n\tqueue := New[string]()\n\tit := queue.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestQueueIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tqueue := New[string]()\n\t\tit := queue.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tqueue := New[string]()\n\t\tqueue.Enqueue(\"xx\")\n\t\tqueue.Enqueue(\"yy\")\n\t\tit := queue.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tqueue := New[string]()\n\t\tqueue.Enqueue(\"aa\")\n\t\tqueue.Enqueue(\"bb\")\n\t\tqueue.Enqueue(\"cc\")\n\t\tit := queue.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestQueueSerialization(t *testing.T) {\n\tqueue := New[string]()\n\tqueue.Enqueue(\"a\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"c\")\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, queue.Values(), []string{\"a\", \"b\", \"c\"})\n\t\tif actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := queue.ToJSON()\n\tassert()\n\n\terr = queue.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", queue})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &queue)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestQueueString(t *testing.T) {\n\tc := New[int]()\n\tc.Enqueue(1)\n\tif !strings.HasPrefix(c.String(), \"LinkedListQueue\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkEnqueue(b *testing.B, queue *Queue[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Enqueue(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkDequeue(b *testing.B, queue *Queue[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Dequeue()\n\t\t}\n\t}\n}\n\nfunc BenchmarkArrayQueueDequeue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueDequeue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := New[int]()\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkArrayQueueEnqueue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n"
  },
  {
    "path": "queues/linkedlistqueue/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedlistqueue\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Queue[int])(nil)\nvar _ containers.JSONDeserializer = (*Queue[int])(nil)\n\n// ToJSON outputs the JSON representation of the queue.\nfunc (queue *Queue[T]) ToJSON() ([]byte, error) {\n\treturn queue.list.ToJSON()\n}\n\n// FromJSON populates the queue from the input JSON representation.\nfunc (queue *Queue[T]) FromJSON(data []byte) error {\n\treturn queue.list.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (queue *Queue[T]) UnmarshalJSON(bytes []byte) error {\n\treturn queue.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (queue *Queue[T]) MarshalJSON() ([]byte, error) {\n\treturn queue.ToJSON()\n}\n"
  },
  {
    "path": "queues/priorityqueue/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage priorityqueue\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\t\"github.com/emirpasic/gods/v2/trees/binaryheap\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\titerator *binaryheap.Iterator[T]\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (queue *Queue[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{iterator: queue.heap.Iterator()}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\treturn iterator.iterator.Next()\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\treturn iterator.iterator.Prev()\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\treturn iterator.iterator.Value()\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.iterator.Index()\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.iterator.Begin()\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.iterator.End()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\treturn iterator.iterator.First()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\treturn iterator.iterator.Last()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\treturn iterator.iterator.NextTo(f)\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\treturn iterator.iterator.PrevTo(f)\n}\n"
  },
  {
    "path": "queues/priorityqueue/priorityqueue.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package priorityqueue implements a priority queue backed by binary queue.\n//\n// An unbounded priority queue based on a priority queue.\n// The elements of the priority queue are ordered by a comparator provided at queue construction time.\n//\n// The heap of this queue is the least/smallest element with respect to the specified ordering.\n// If multiple elements are tied for least value, the heap is one of those elements arbitrarily.\n//\n// Structure is not thread safe.\n//\n// References: https://en.wikipedia.org/wiki/Priority_queue\npackage priorityqueue\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/queues\"\n\t\"github.com/emirpasic/gods/v2/trees/binaryheap\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Queue implementation\nvar _ queues.Queue[int] = (*Queue[int])(nil)\n\n// Queue holds elements in an array-list\ntype Queue[T comparable] struct {\n\theap       *binaryheap.Heap[T]\n\tComparator utils.Comparator[T]\n}\n\nfunc New[T cmp.Ordered]() *Queue[T] {\n\treturn NewWith[T](cmp.Compare[T])\n}\n\n// NewWith instantiates a new empty queue with the custom comparator.\nfunc NewWith[T comparable](comparator utils.Comparator[T]) *Queue[T] {\n\treturn &Queue[T]{heap: binaryheap.NewWith(comparator), Comparator: comparator}\n}\n\n// Enqueue adds a value to the end of the queue\nfunc (queue *Queue[T]) Enqueue(value T) {\n\tqueue.heap.Push(value)\n}\n\n// Dequeue removes first element of the queue and returns it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to dequeue.\nfunc (queue *Queue[T]) Dequeue() (value T, ok bool) {\n\treturn queue.heap.Pop()\n}\n\n// Peek returns top element on the queue without removing it, or nil if queue is empty.\n// Second return parameter is true, unless the queue was empty and there was nothing to peek.\nfunc (queue *Queue[T]) Peek() (value T, ok bool) {\n\treturn queue.heap.Peek()\n}\n\n// Empty returns true if queue does not contain any elements.\nfunc (queue *Queue[T]) Empty() bool {\n\treturn queue.heap.Empty()\n}\n\n// Size returns number of elements within the queue.\nfunc (queue *Queue[T]) Size() int {\n\treturn queue.heap.Size()\n}\n\n// Clear removes all elements from the queue.\nfunc (queue *Queue[T]) Clear() {\n\tqueue.heap.Clear()\n}\n\n// Values returns all elements in the queue.\nfunc (queue *Queue[T]) Values() []T {\n\treturn queue.heap.Values()\n}\n\n// String returns a string representation of container\nfunc (queue *Queue[T]) String() string {\n\tstr := \"PriorityQueue\\n\"\n\tvalues := make([]string, queue.heap.Size(), queue.heap.Size())\n\tfor index, value := range queue.heap.Values() {\n\t\tvalues[index] = fmt.Sprintf(\"%v\", value)\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n"
  },
  {
    "path": "queues/priorityqueue/priorityqueue_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage priorityqueue\n\nimport (\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n)\n\ntype Element struct {\n\tpriority int\n\tname     string\n}\n\nfunc (element Element) String() string {\n\treturn fmt.Sprintf(\"{%v %v}\", element.priority, element.name)\n}\n\n// Comparator function (sort by priority value in descending order)\nfunc byPriority(a, b Element) int {\n\treturn -cmp.Compare(a.priority, b.priority) // Note \"-\" for descending order\n}\n\nfunc TestBinaryQueueEnqueue(t *testing.T) {\n\tqueue := NewWith[Element](byPriority)\n\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\ta := Element{name: \"a\", priority: 1}\n\tc := Element{name: \"c\", priority: 3}\n\tb := Element{name: \"b\", priority: 2}\n\n\tqueue.Enqueue(a)\n\tqueue.Enqueue(c)\n\tqueue.Enqueue(b)\n\n\tit := queue.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value.name, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value.name, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value.name, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\n\tif actualValue := queue.Values(); actualValue[0].name != \"c\" || actualValue[1].name != \"b\" || actualValue[2].name != \"a\" {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, `[{3 c} {2 b} {1 a}]`)\n\t}\n}\n\nfunc TestBinaryQueueEnqueueBulk(t *testing.T) {\n\tqueue := New[int]()\n\n\tqueue.Enqueue(15)\n\tqueue.Enqueue(20)\n\tqueue.Enqueue(3)\n\tqueue.Enqueue(1)\n\tqueue.Enqueue(2)\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 15 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 15)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 20 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 20)\n\t}\n\n\tqueue.Clear()\n\tif actualValue := queue.Empty(); !actualValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestBinaryQueueDequeue(t *testing.T) {\n\tqueue := New[int]()\n\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\tqueue.Enqueue(3)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(1)\n\tqueue.Dequeue() // removes 1\n\n\tif actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := queue.Dequeue(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := queue.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := queue.Values(); len(actualValue) != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[]\")\n\t}\n}\n\nfunc TestBinaryQueueRandom(t *testing.T) {\n\tqueue := New[int]()\n\n\trand.Seed(3)\n\tfor i := 0; i < 10000; i++ {\n\t\tr := int(rand.Int31n(30))\n\t\tqueue.Enqueue(r)\n\t}\n\n\tprev, _ := queue.Dequeue()\n\tfor !queue.Empty() {\n\t\tcurr, _ := queue.Dequeue()\n\t\tif prev > curr {\n\t\t\tt.Errorf(\"Queue property invalidated. prev: %v current: %v\", prev, curr)\n\t\t}\n\t\tprev = curr\n\t}\n}\n\nfunc TestBinaryQueueIteratorOnEmpty(t *testing.T) {\n\tqueue := New[int]()\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty queue\")\n\t}\n}\n\nfunc TestBinaryQueueIteratorNext(t *testing.T) {\n\tqueue := New[int]()\n\tqueue.Enqueue(3)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(1)\n\n\tit := queue.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBinaryQueueIteratorPrev(t *testing.T) {\n\tqueue := New[int]()\n\tqueue.Enqueue(3)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(1)\n\n\tit := queue.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, 3-count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBinaryQueueIteratorBegin(t *testing.T) {\n\tqueue := New[int]()\n\tit := queue.Iterator()\n\tit.Begin()\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(3)\n\tqueue.Enqueue(1)\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != 1 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, 1)\n\t}\n}\n\nfunc TestBinaryQueueIteratorEnd(t *testing.T) {\n\tqueue := New[int]()\n\tit := queue.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tqueue.Enqueue(3)\n\tqueue.Enqueue(2)\n\tqueue.Enqueue(1)\n\tit.End()\n\tif index := it.Index(); index != queue.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, queue.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != queue.Size()-1 || value != 3 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, queue.Size()-1, 3)\n\t}\n}\n\nfunc TestBinaryQueueIteratorFirst(t *testing.T) {\n\tqueue := New[int]()\n\tit := queue.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tqueue.Enqueue(3) // [3]\n\tqueue.Enqueue(2) // [2,3]\n\tqueue.Enqueue(1) // [1,3,2](2 swapped with 1, hence last)\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != 1 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, 1)\n\t}\n}\n\nfunc TestBinaryQueueIteratorLast(t *testing.T) {\n\ttree := New[int]()\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\ttree.Enqueue(2)\n\ttree.Enqueue(3)\n\ttree.Enqueue(1)\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != 3 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, 3)\n\t}\n}\n\nfunc TestBinaryQueueIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\ttree := New[string]()\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Enqueue(\"xx\")\n\t\ttree.Enqueue(\"yy\")\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Enqueue(\"aa\")\n\t\ttree.Enqueue(\"bb\")\n\t\ttree.Enqueue(\"cc\")\n\t\tit := tree.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestBinaryQueueIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\ttree := New[string]()\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Enqueue(\"xx\")\n\t\ttree.Enqueue(\"yy\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Enqueue(\"aa\")\n\t\ttree.Enqueue(\"bb\")\n\t\ttree.Enqueue(\"cc\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestBinaryQueueSerialization(t *testing.T) {\n\tqueue := New[string]()\n\n\tqueue.Enqueue(\"c\")\n\tqueue.Enqueue(\"b\")\n\tqueue.Enqueue(\"a\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue := queue.Values(); actualValue[0] != \"a\" || actualValue[1] != \"b\" || actualValue[2] != \"c\" {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[1,3,2]\")\n\t\t}\n\t\tif actualValue := queue.Size(); actualValue != 3 {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t\t}\n\t\tif actualValue, ok := queue.Peek(); actualValue != \"a\" || !ok {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"a\")\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := queue.ToJSON()\n\tassert()\n\n\terr = queue.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", queue})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &queue)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestBTreeString(t *testing.T) {\n\tc := New[int]()\n\tc.Enqueue(1)\n\tif !strings.HasPrefix(c.String(), \"PriorityQueue\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkEnqueue(b *testing.B, queue *Queue[Element], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Enqueue(Element{})\n\t\t}\n\t}\n}\n\nfunc benchmarkDequeue(b *testing.B, queue *Queue[Element], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tqueue.Dequeue()\n\t\t}\n\t}\n}\n\nfunc BenchmarkBinaryQueueDequeue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueDequeue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueDequeue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueDequeue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkDequeue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueEnqueue100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tqueue := NewWith(byPriority)\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueEnqueue1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueEnqueue10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n\nfunc BenchmarkBinaryQueueEnqueue100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tqueue := NewWith[Element](byPriority)\n\tfor n := 0; n < size; n++ {\n\t\tqueue.Enqueue(Element{})\n\t}\n\tb.StartTimer()\n\tbenchmarkEnqueue(b, queue, size)\n}\n"
  },
  {
    "path": "queues/priorityqueue/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage priorityqueue\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Queue[int])(nil)\nvar _ containers.JSONDeserializer = (*Queue[int])(nil)\n\n// ToJSON outputs the JSON representation of the queue.\nfunc (queue *Queue[T]) ToJSON() ([]byte, error) {\n\treturn queue.heap.ToJSON()\n}\n\n// FromJSON populates the queue from the input JSON representation.\nfunc (queue *Queue[T]) FromJSON(data []byte) error {\n\treturn queue.heap.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (queue *Queue[T]) UnmarshalJSON(bytes []byte) error {\n\treturn queue.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (queue *Queue[T]) MarshalJSON() ([]byte, error) {\n\treturn queue.ToJSON()\n}\n"
  },
  {
    "path": "queues/queues.go",
    "content": "// Copyright (c) 2021, Aryan Ahadinia. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package queues provides an abstract Queue interface.\n//\n// In computer science, a queue is a collection of entities that are maintained in a sequence and can be modified by the addition of entities at one end of the sequence and the removal of entities from the other end of the sequence. By convention, the end of the sequence at which elements are added is called the back, tail, or rear of the queue, and the end at which elements are removed is called the head or front of the queue, analogously to the words used when people line up to wait for goods or services.\n// The operation of adding an element to the rear of the queue is known as enqueue, and the operation of removing an element from the front is known as dequeue. Other operations may also be allowed, often including a peek or front operation that returns the value of the next element to be dequeued without remove it.\n//\n// Reference: https://en.wikipedia.org/wiki/Queue_(abstract_data_type)\npackage queues\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Queue interface that all queues implement\ntype Queue[T comparable] interface {\n\tEnqueue(value T)\n\tDequeue() (value T, ok bool)\n\tPeek() (value T, ok bool)\n\n\tcontainers.Container[T]\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n"
  },
  {
    "path": "sets/hashset/hashset.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package hashset implements a set backed by a hash table.\n//\n// Structure is not thread safe.\n//\n// References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29\npackage hashset\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/sets\"\n)\n\n// Assert Set implementation\nvar _ sets.Set[int] = (*Set[int])(nil)\n\n// Set holds elements in go's native map\ntype Set[T comparable] struct {\n\titems map[T]struct{}\n}\n\nvar itemExists = struct{}{}\n\n// New instantiates a new empty set and adds the passed values, if any, to the set\nfunc New[T comparable](values ...T) *Set[T] {\n\tset := &Set[T]{items: make(map[T]struct{})}\n\tif len(values) > 0 {\n\t\tset.Add(values...)\n\t}\n\treturn set\n}\n\n// Add adds the items (one or more) to the set.\nfunc (set *Set[T]) Add(items ...T) {\n\tfor _, item := range items {\n\t\tset.items[item] = itemExists\n\t}\n}\n\n// Remove removes the items (one or more) from the set.\nfunc (set *Set[T]) Remove(items ...T) {\n\tfor _, item := range items {\n\t\tdelete(set.items, item)\n\t}\n}\n\n// Contains check if items (one or more) are present in the set.\n// All items have to be present in the set for the method to return true.\n// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.\nfunc (set *Set[T]) Contains(items ...T) bool {\n\tfor _, item := range items {\n\t\tif _, contains := set.items[item]; !contains {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Empty returns true if set does not contain any elements.\nfunc (set *Set[T]) Empty() bool {\n\treturn set.Size() == 0\n}\n\n// Size returns number of elements within the set.\nfunc (set *Set[T]) Size() int {\n\treturn len(set.items)\n}\n\n// Clear clears all values in the set.\nfunc (set *Set[T]) Clear() {\n\tset.items = make(map[T]struct{})\n}\n\n// Values returns all items in the set.\nfunc (set *Set[T]) Values() []T {\n\tvalues := make([]T, set.Size())\n\tcount := 0\n\tfor item := range set.items {\n\t\tvalues[count] = item\n\t\tcount++\n\t}\n\treturn values\n}\n\n// String returns a string representation of container\nfunc (set *Set[T]) String() string {\n\tstr := \"HashSet\\n\"\n\titems := []string{}\n\tfor k := range set.items {\n\t\titems = append(items, fmt.Sprintf(\"%v\", k))\n\t}\n\tstr += strings.Join(items, \", \")\n\treturn str\n}\n\n// Intersection returns the intersection between two sets.\n// The new set consists of all elements that are both in \"set\" and \"another\".\n// Ref: https://en.wikipedia.org/wiki/Intersection_(set_theory)\nfunc (set *Set[T]) Intersection(another *Set[T]) *Set[T] {\n\tresult := New[T]()\n\n\t// Iterate over smaller set (optimization)\n\tif set.Size() <= another.Size() {\n\t\tfor item := range set.items {\n\t\t\tif _, contains := another.items[item]; contains {\n\t\t\t\tresult.Add(item)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor item := range another.items {\n\t\t\tif _, contains := set.items[item]; contains {\n\t\t\t\tresult.Add(item)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\n// Union returns the union of two sets.\n// The new set consists of all elements that are in \"set\" or \"another\" (possibly both).\n// Ref: https://en.wikipedia.org/wiki/Union_(set_theory)\nfunc (set *Set[T]) Union(another *Set[T]) *Set[T] {\n\tresult := New[T]()\n\n\tfor item := range set.items {\n\t\tresult.Add(item)\n\t}\n\tfor item := range another.items {\n\t\tresult.Add(item)\n\t}\n\n\treturn result\n}\n\n// Difference returns the difference between two sets.\n// The new set consists of all elements that are in \"set\" but not in \"another\".\n// Ref: https://proofwiki.org/wiki/Definition:Set_Difference\nfunc (set *Set[T]) Difference(another *Set[T]) *Set[T] {\n\tresult := New[T]()\n\n\tfor item := range set.items {\n\t\tif _, contains := another.items[item]; !contains {\n\t\t\tresult.Add(item)\n\t\t}\n\t}\n\n\treturn result\n}\n"
  },
  {
    "path": "sets/hashset/hashset_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage hashset\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestSetNew(t *testing.T) {\n\tset := New(2, 1)\n\n\tif actualValue := set.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue := set.Contains(1); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(2); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(3); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetAdd(t *testing.T) {\n\tset := New[int]()\n\tset.Add()\n\tset.Add(1)\n\tset.Add(2)\n\tset.Add(2, 3)\n\tset.Add()\n\tif actualValue := set.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := set.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n}\n\nfunc TestSetContains(t *testing.T) {\n\tset := New[int]()\n\tset.Add(3, 1, 2)\n\tset.Add(2, 3)\n\tset.Add()\n\tif actualValue := set.Contains(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1, 2, 3); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1, 2, 3, 4); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n}\n\nfunc TestSetRemove(t *testing.T) {\n\tset := New[int]()\n\tset.Add(3, 1, 2)\n\tset.Remove()\n\tif actualValue := set.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tset.Remove(1)\n\tif actualValue := set.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tset.Remove(3)\n\tset.Remove(3)\n\tset.Remove()\n\tset.Remove(2)\n\tif actualValue := set.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestSetSerialization(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue := set.Contains(\"a\", \"b\", \"c\"); actualValue != true {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := set.ToJSON()\n\tassert()\n\n\terr = set.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", set})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &set)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestSetString(t *testing.T) {\n\tc := New[int]()\n\tc.Add(1)\n\tif !strings.HasPrefix(c.String(), \"HashSet\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc TestSetIntersection(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tintersection := set.Intersection(another)\n\tif actualValue, expectedValue := intersection.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tintersection = set.Intersection(another)\n\n\tif actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := intersection.Contains(\"c\", \"d\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetUnion(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tunion := set.Union(another)\n\tif actualValue, expectedValue := union.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tunion = set.Union(another)\n\n\tif actualValue, expectedValue := union.Size(), 6; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := union.Contains(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetDifference(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tdifference := set.Difference(another)\n\tif actualValue, expectedValue := difference.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tdifference = set.Difference(another)\n\n\tif actualValue, expectedValue := difference.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := difference.Contains(\"a\", \"b\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc benchmarkContains(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Contains(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkAdd(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Add(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkHashSetContains100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetContains1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetContains10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetContains100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n"
  },
  {
    "path": "sets/hashset/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage hashset\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Set[int])(nil)\nvar _ containers.JSONDeserializer = (*Set[int])(nil)\n\n// ToJSON outputs the JSON representation of the set.\nfunc (set *Set[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(set.Values())\n}\n\n// FromJSON populates the set from the input JSON representation.\nfunc (set *Set[T]) FromJSON(data []byte) error {\n\tvar elements []T\n\terr := json.Unmarshal(data, &elements)\n\tif err == nil {\n\t\tset.Clear()\n\t\tset.Add(elements...)\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (set *Set[T]) UnmarshalJSON(bytes []byte) error {\n\treturn set.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (set *Set[T]) MarshalJSON() ([]byte, error) {\n\treturn set.ToJSON()\n}\n"
  },
  {
    "path": "sets/linkedhashset/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashset\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithIndex[int] = (*Set[int])(nil)\n\n// Each calls the given function once for each element, passing that element's index and value.\nfunc (set *Set[T]) Each(f func(index int, value T)) {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Index(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a\n// container containing the values returned by the given function.\nfunc (set *Set[T]) Map(f func(index int, value T) T) *Set[T] {\n\tnewSet := New[T]()\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tnewSet.Add(f(iterator.Index(), iterator.Value()))\n\t}\n\treturn newSet\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (set *Set[T]) Select(f func(index int, value T) bool) *Set[T] {\n\tnewSet := New[T]()\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\tnewSet.Add(iterator.Value())\n\t\t}\n\t}\n\treturn newSet\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (set *Set[T]) Any(f func(index int, value T) bool) bool {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (set *Set[T]) All(f func(index int, value T) bool) bool {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Index(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (index,value) for which the function is true or -1,nil otherwise\n// if no element matches the criteria.\nfunc (set *Set[T]) Find(f func(index int, value T) bool) (int, T) {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn iterator.Index(), iterator.Value()\n\t\t}\n\t}\n\tvar t T\n\treturn -1, t\n}\n"
  },
  {
    "path": "sets/linkedhashset/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashset\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\t\"github.com/emirpasic/gods/v2/lists/doublylinkedlist\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[T comparable] struct {\n\titerator doublylinkedlist.Iterator[T]\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (set *Set[T]) Iterator() Iterator[T] {\n\treturn Iterator[T]{iterator: set.ordering.Iterator()}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\treturn iterator.iterator.Next()\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\treturn iterator.iterator.Prev()\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\treturn iterator.iterator.Value()\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.iterator.Index()\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.iterator.Begin()\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.iterator.End()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\treturn iterator.iterator.First()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\treturn iterator.iterator.Last()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "sets/linkedhashset/linkedhashset.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package linkedhashset is a set that preserves insertion-order.\n//\n// It is backed by a hash table to store values and doubly-linked list to store ordering.\n//\n// Note that insertion-order is not affected if an element is re-inserted into the set.\n//\n// Structure is not thread safe.\n//\n// References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29\npackage linkedhashset\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/doublylinkedlist\"\n\t\"github.com/emirpasic/gods/v2/sets\"\n)\n\n// Assert Set implementation\nvar _ sets.Set[int] = (*Set[int])(nil)\n\n// Set holds elements in go's native map\ntype Set[T comparable] struct {\n\ttable    map[T]struct{}\n\tordering *doublylinkedlist.List[T]\n}\n\nvar itemExists = struct{}{}\n\n// New instantiates a new empty set and adds the passed values, if any, to the set\nfunc New[T comparable](values ...T) *Set[T] {\n\tset := &Set[T]{\n\t\ttable:    make(map[T]struct{}),\n\t\tordering: doublylinkedlist.New[T](),\n\t}\n\tif len(values) > 0 {\n\t\tset.Add(values...)\n\t}\n\treturn set\n}\n\n// Add adds the items (one or more) to the set.\n// Note that insertion-order is not affected if an element is re-inserted into the set.\nfunc (set *Set[T]) Add(items ...T) {\n\tfor _, item := range items {\n\t\tif _, contains := set.table[item]; !contains {\n\t\t\tset.table[item] = itemExists\n\t\t\tset.ordering.Append(item)\n\t\t}\n\t}\n}\n\n// Remove removes the items (one or more) from the set.\n// Slow operation, worst-case O(n^2).\nfunc (set *Set[T]) Remove(items ...T) {\n\tfor _, item := range items {\n\t\tif _, contains := set.table[item]; contains {\n\t\t\tdelete(set.table, item)\n\t\t\tindex := set.ordering.IndexOf(item)\n\t\t\tset.ordering.Remove(index)\n\t\t}\n\t}\n}\n\n// Contains check if items (one or more) are present in the set.\n// All items have to be present in the set for the method to return true.\n// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.\nfunc (set *Set[T]) Contains(items ...T) bool {\n\tfor _, item := range items {\n\t\tif _, contains := set.table[item]; !contains {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Empty returns true if set does not contain any elements.\nfunc (set *Set[T]) Empty() bool {\n\treturn set.Size() == 0\n}\n\n// Size returns number of elements within the set.\nfunc (set *Set[T]) Size() int {\n\treturn set.ordering.Size()\n}\n\n// Clear clears all values in the set.\nfunc (set *Set[T]) Clear() {\n\tset.table = make(map[T]struct{})\n\tset.ordering.Clear()\n}\n\n// Values returns all items in the set.\nfunc (set *Set[T]) Values() []T {\n\tvalues := make([]T, set.Size())\n\tit := set.Iterator()\n\tfor it.Next() {\n\t\tvalues[it.Index()] = it.Value()\n\t}\n\treturn values\n}\n\n// String returns a string representation of container\nfunc (set *Set[T]) String() string {\n\tstr := \"LinkedHashSet\\n\"\n\titems := []string{}\n\tit := set.Iterator()\n\tfor it.Next() {\n\t\titems = append(items, fmt.Sprintf(\"%v\", it.Value()))\n\t}\n\tstr += strings.Join(items, \", \")\n\treturn str\n}\n\n// Intersection returns the intersection between two sets.\n// The new set consists of all elements that are both in \"set\" and \"another\".\n// Ref: https://en.wikipedia.org/wiki/Intersection_(set_theory)\nfunc (set *Set[T]) Intersection(another *Set[T]) *Set[T] {\n\tresult := New[T]()\n\n\t// Iterate over smaller set (optimization)\n\tif set.Size() <= another.Size() {\n\t\tfor item := range set.table {\n\t\t\tif _, contains := another.table[item]; contains {\n\t\t\t\tresult.Add(item)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor item := range another.table {\n\t\t\tif _, contains := set.table[item]; contains {\n\t\t\t\tresult.Add(item)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\n// Union returns the union of two sets.\n// The new set consists of all elements that are in \"set\" or \"another\" (possibly both).\n// Ref: https://en.wikipedia.org/wiki/Union_(set_theory)\nfunc (set *Set[T]) Union(another *Set[T]) *Set[T] {\n\tresult := New[T]()\n\n\tfor item := range set.table {\n\t\tresult.Add(item)\n\t}\n\tfor item := range another.table {\n\t\tresult.Add(item)\n\t}\n\n\treturn result\n}\n\n// Difference returns the difference between two sets.\n// The new set consists of all elements that are in \"set\" but not in \"another\".\n// Ref: https://proofwiki.org/wiki/Definition:Set_Difference\nfunc (set *Set[T]) Difference(another *Set[T]) *Set[T] {\n\tresult := New[T]()\n\n\tfor item := range set.table {\n\t\tif _, contains := another.table[item]; !contains {\n\t\t\tresult.Add(item)\n\t\t}\n\t}\n\n\treturn result\n}\n"
  },
  {
    "path": "sets/linkedhashset/linkedhashset_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashset\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestSetNew(t *testing.T) {\n\tset := New(2, 1)\n\n\tif actualValue := set.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue := set.Contains(1); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(2); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(3); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetAdd(t *testing.T) {\n\tset := New[int]()\n\tset.Add()\n\tset.Add(1)\n\tset.Add(2)\n\tset.Add(2, 3)\n\tset.Add()\n\tif actualValue := set.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := set.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n}\n\nfunc TestSetContains(t *testing.T) {\n\tset := New[int]()\n\tset.Add(3, 1, 2)\n\tset.Add(2, 3)\n\tset.Add()\n\tif actualValue := set.Contains(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1, 2, 3); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1, 2, 3, 4); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n}\n\nfunc TestSetRemove(t *testing.T) {\n\tset := New[int]()\n\tset.Add(3, 1, 2)\n\tset.Remove()\n\tif actualValue := set.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tset.Remove(1)\n\tif actualValue := set.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tset.Remove(3)\n\tset.Remove(3)\n\tset.Remove()\n\tset.Remove(2)\n\tif actualValue := set.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestSetEach(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tset.Each(func(index int, value string) {\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestSetMap(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tmappedSet := set.Map(func(index int, value string) string {\n\t\treturn \"mapped: \" + value\n\t})\n\tif actualValue, expectedValue := mappedSet.Contains(\"mapped: c\", \"mapped: b\", \"mapped: a\"), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := mappedSet.Contains(\"mapped: c\", \"mapped: b\", \"mapped: x\"), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif mappedSet.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedSet.Size(), 3)\n\t}\n}\n\nfunc TestSetSelect(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tselectedSet := set.Select(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif actualValue, expectedValue := selectedSet.Contains(\"a\", \"b\"), true; actualValue != expectedValue {\n\t\tfmt.Println(\"A: \", selectedSet.Contains(\"b\"))\n\t\tt.Errorf(\"Got %v (%v) expected %v (%v)\", actualValue, selectedSet.Values(), expectedValue, \"[a b]\")\n\t}\n\tif actualValue, expectedValue := selectedSet.Contains(\"a\", \"b\", \"c\"), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v (%v) expected %v (%v)\", actualValue, selectedSet.Values(), expectedValue, \"[a b]\")\n\t}\n\tif selectedSet.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedSet.Size(), 3)\n\t}\n}\n\nfunc TestSetAny(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tany := set.Any(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = set.Any(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\n\nfunc TestSetAll(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tall := set.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = set.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\n\nfunc TestSetFind(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tfoundIndex, foundValue := set.Find(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif foundValue != \"c\" || foundIndex != 0 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, \"c\", 0)\n\t}\n\tfoundIndex, foundValue = set.Find(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif foundValue != \"\" || foundIndex != -1 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, nil, nil)\n\t}\n}\n\nfunc TestSetChaining(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n}\n\nfunc TestSetIteratorPrevOnEmpty(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t}\n}\n\nfunc TestSetIteratorNext(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tit := set.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestSetIteratorPrev(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tit := set.Iterator()\n\tfor it.Prev() {\n\t}\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestSetIteratorBegin(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\tit.Begin()\n\tset.Add(\"a\", \"b\", \"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestSetIteratorEnd(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\")\n\tit.End()\n\tif index := it.Index(); index != set.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, set.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != set.Size()-1 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, set.Size()-1, \"c\")\n\t}\n}\n\nfunc TestSetIteratorFirst(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\tit := set.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestSetIteratorLast(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\tit := set.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 3, \"c\")\n\t}\n}\n\nfunc TestSetIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tset := New[string]()\n\t\tit := set.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"xx\", \"yy\")\n\t\tit := set.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := set.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestSetIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tset := New[string]()\n\t\tit := set.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"xx\", \"yy\")\n\t\tit := set.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := set.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestSetSerialization(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue := set.Contains(\"a\", \"b\", \"c\"); actualValue != true {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := set.ToJSON()\n\tassert()\n\n\terr = set.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", set})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &set)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestSetString(t *testing.T) {\n\tc := New[int]()\n\tc.Add(1)\n\tif !strings.HasPrefix(c.String(), \"LinkedHashSet\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc TestSetIntersection(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tintersection := set.Intersection(another)\n\tif actualValue, expectedValue := intersection.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tintersection = set.Intersection(another)\n\n\tif actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := intersection.Contains(\"c\", \"d\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetUnion(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tunion := set.Union(another)\n\tif actualValue, expectedValue := union.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tunion = set.Union(another)\n\n\tif actualValue, expectedValue := union.Size(), 6; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := union.Contains(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetDifference(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tdifference := set.Difference(another)\n\tif actualValue, expectedValue := difference.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tdifference = set.Difference(another)\n\n\tif actualValue, expectedValue := difference.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := difference.Contains(\"a\", \"b\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc benchmarkContains(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Contains(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkAdd(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Add(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkHashSetContains100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetContains1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetContains10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetContains100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetAdd100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkHashSetRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n"
  },
  {
    "path": "sets/linkedhashset/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedhashset\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Set[int])(nil)\nvar _ containers.JSONDeserializer = (*Set[int])(nil)\n\n// ToJSON outputs the JSON representation of the set.\nfunc (set *Set[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(set.Values())\n}\n\n// FromJSON populates the set from the input JSON representation.\nfunc (set *Set[T]) FromJSON(data []byte) error {\n\tvar elements []T\n\terr := json.Unmarshal(data, &elements)\n\tif err == nil {\n\t\tset.Clear()\n\t\tset.Add(elements...)\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (set *Set[T]) UnmarshalJSON(bytes []byte) error {\n\treturn set.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (set *Set[T]) MarshalJSON() ([]byte, error) {\n\treturn set.ToJSON()\n}\n"
  },
  {
    "path": "sets/sets.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package sets provides an abstract Set interface.\n//\n// 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.\n//\n// Reference: https://en.wikipedia.org/wiki/Set_%28abstract_data_type%29\npackage sets\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Set interface that all sets implement\ntype Set[T comparable] interface {\n\tAdd(elements ...T)\n\tRemove(elements ...T)\n\tContains(elements ...T) bool\n\n\tcontainers.Container[T]\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n"
  },
  {
    "path": "sets/treeset/enumerable.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treeset\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// Assert Enumerable implementation\nvar _ containers.EnumerableWithIndex[int] = (*Set[int])(nil)\n\n// Each calls the given function once for each element, passing that element's index and value.\nfunc (set *Set[T]) Each(f func(index int, value T)) {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tf(iterator.Index(), iterator.Value())\n\t}\n}\n\n// Map invokes the given function once for each element and returns a\n// container containing the values returned by the given function.\nfunc (set *Set[T]) Map(f func(index int, value T) T) *Set[T] {\n\tnewSet := &Set[T]{tree: rbt.NewWith[T, struct{}](set.tree.Comparator)}\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tnewSet.Add(f(iterator.Index(), iterator.Value()))\n\t}\n\treturn newSet\n}\n\n// Select returns a new container containing all elements for which the given function returns a true value.\nfunc (set *Set[T]) Select(f func(index int, value T) bool) *Set[T] {\n\tnewSet := &Set[T]{tree: rbt.NewWith[T, struct{}](set.tree.Comparator)}\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\tnewSet.Add(iterator.Value())\n\t\t}\n\t}\n\treturn newSet\n}\n\n// Any passes each element of the container to the given function and\n// returns true if the function ever returns true for any element.\nfunc (set *Set[T]) Any(f func(index int, value T) bool) bool {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// All passes each element of the container to the given function and\n// returns true if the function returns true for all elements.\nfunc (set *Set[T]) All(f func(index int, value T) bool) bool {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif !f(iterator.Index(), iterator.Value()) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Find passes each element of the container to the given function and returns\n// the first (index,value) for which the function is true or -1,nil otherwise\n// if no element matches the criteria.\nfunc (set *Set[T]) Find(f func(index int, value T) bool) (int, T) {\n\titerator := set.Iterator()\n\tfor iterator.Next() {\n\t\tif f(iterator.Index(), iterator.Value()) {\n\t\t\treturn iterator.Index(), iterator.Value()\n\t\t}\n\t}\n\tvar t T\n\treturn -1, t\n}\n"
  },
  {
    "path": "sets/treeset/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treeset\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\tindex    int\n\titerator *rbt.Iterator[T, struct{}]\n\ttree     *rbt.Tree[T, struct{}]\n}\n\n// Iterator holding the iterator's state\nfunc (set *Set[T]) Iterator() Iterator[T] {\n\treturn Iterator[T]{index: -1, iterator: set.tree.Iterator(), tree: set.tree}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.tree.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.iterator.Next()\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\treturn iterator.iterator.Prev()\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\treturn iterator.iterator.Key()\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n\titerator.iterator.Begin()\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.tree.Size()\n\titerator.iterator.End()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "sets/treeset/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treeset\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Set[int])(nil)\nvar _ containers.JSONDeserializer = (*Set[int])(nil)\n\n// ToJSON outputs the JSON representation of the set.\nfunc (set *Set[T]) ToJSON() ([]byte, error) {\n\treturn json.Marshal(set.Values())\n}\n\n// FromJSON populates the set from the input JSON representation.\nfunc (set *Set[T]) FromJSON(data []byte) error {\n\tvar elements []T\n\terr := json.Unmarshal(data, &elements)\n\tif err == nil {\n\t\tset.Clear()\n\t\tset.Add(elements...)\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (set *Set[T]) UnmarshalJSON(bytes []byte) error {\n\treturn set.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (set *Set[T]) MarshalJSON() ([]byte, error) {\n\treturn set.ToJSON()\n}\n"
  },
  {
    "path": "sets/treeset/treeset.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package treeset implements a tree backed by a red-black tree.\n//\n// Structure is not thread safe.\n//\n// Reference: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29\npackage treeset\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/sets\"\n\trbt \"github.com/emirpasic/gods/v2/trees/redblacktree\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Set implementation\nvar _ sets.Set[int] = (*Set[int])(nil)\n\n// Set holds elements in a red-black tree\ntype Set[T comparable] struct {\n\ttree *rbt.Tree[T, struct{}]\n}\n\nvar itemExists = struct{}{}\n\nfunc New[T cmp.Ordered](values ...T) *Set[T] {\n\treturn NewWith[T](cmp.Compare[T], values...)\n}\n\n// NewWith instantiates a new empty set with the custom comparator.\nfunc NewWith[T comparable](comparator utils.Comparator[T], values ...T) *Set[T] {\n\tset := &Set[T]{tree: rbt.NewWith[T, struct{}](comparator)}\n\tif len(values) > 0 {\n\t\tset.Add(values...)\n\t}\n\treturn set\n}\n\n// Add adds the items (one or more) to the set.\nfunc (set *Set[T]) Add(items ...T) {\n\tfor _, item := range items {\n\t\tset.tree.Put(item, itemExists)\n\t}\n}\n\n// Remove removes the items (one or more) from the set.\nfunc (set *Set[T]) Remove(items ...T) {\n\tfor _, item := range items {\n\t\tset.tree.Remove(item)\n\t}\n}\n\n// Contains checks weather items (one or more) are present in the set.\n// All items have to be present in the set for the method to return true.\n// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.\nfunc (set *Set[T]) Contains(items ...T) bool {\n\tfor _, item := range items {\n\t\tif _, contains := set.tree.Get(item); !contains {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Empty returns true if set does not contain any elements.\nfunc (set *Set[T]) Empty() bool {\n\treturn set.tree.Size() == 0\n}\n\n// Size returns number of elements within the set.\nfunc (set *Set[T]) Size() int {\n\treturn set.tree.Size()\n}\n\n// Clear clears all values in the set.\nfunc (set *Set[T]) Clear() {\n\tset.tree.Clear()\n}\n\n// Values returns all items in the set.\nfunc (set *Set[T]) Values() []T {\n\treturn set.tree.Keys()\n}\n\n// String returns a string representation of container\nfunc (set *Set[T]) String() string {\n\tstr := \"TreeSet\\n\"\n\titems := []string{}\n\tfor _, v := range set.tree.Keys() {\n\t\titems = append(items, fmt.Sprintf(\"%v\", v))\n\t}\n\tstr += strings.Join(items, \", \")\n\treturn str\n}\n\n// Intersection returns the intersection between two sets.\n// The new set consists of all elements that are both in \"set\" and \"another\".\n// The two sets should have the same comparators, otherwise the result is empty set.\n// Ref: https://en.wikipedia.org/wiki/Intersection_(set_theory)\nfunc (set *Set[T]) Intersection(another *Set[T]) *Set[T] {\n\tresult := NewWith(set.tree.Comparator)\n\n\tsetComparator := reflect.ValueOf(set.tree.Comparator)\n\tanotherComparator := reflect.ValueOf(another.tree.Comparator)\n\tif setComparator.Pointer() != anotherComparator.Pointer() {\n\t\treturn result\n\t}\n\n\t// Iterate over smaller set (optimization)\n\tif set.Size() <= another.Size() {\n\t\tfor it := set.Iterator(); it.Next(); {\n\t\t\tif another.Contains(it.Value()) {\n\t\t\t\tresult.Add(it.Value())\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor it := another.Iterator(); it.Next(); {\n\t\t\tif set.Contains(it.Value()) {\n\t\t\t\tresult.Add(it.Value())\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\n// Union returns the union of two sets.\n// The new set consists of all elements that are in \"set\" or \"another\" (possibly both).\n// The two sets should have the same comparators, otherwise the result is empty set.\n// Ref: https://en.wikipedia.org/wiki/Union_(set_theory)\nfunc (set *Set[T]) Union(another *Set[T]) *Set[T] {\n\tresult := NewWith(set.tree.Comparator)\n\n\tsetComparator := reflect.ValueOf(set.tree.Comparator)\n\tanotherComparator := reflect.ValueOf(another.tree.Comparator)\n\tif setComparator.Pointer() != anotherComparator.Pointer() {\n\t\treturn result\n\t}\n\n\tfor it := set.Iterator(); it.Next(); {\n\t\tresult.Add(it.Value())\n\t}\n\tfor it := another.Iterator(); it.Next(); {\n\t\tresult.Add(it.Value())\n\t}\n\n\treturn result\n}\n\n// Difference returns the difference between two sets.\n// The two sets should have the same comparators, otherwise the result is empty set.\n// The new set consists of all elements that are in \"set\" but not in \"another\".\n// Ref: https://proofwiki.org/wiki/Definition:Set_Difference\nfunc (set *Set[T]) Difference(another *Set[T]) *Set[T] {\n\tresult := NewWith(set.tree.Comparator)\n\n\tsetComparator := reflect.ValueOf(set.tree.Comparator)\n\tanotherComparator := reflect.ValueOf(another.tree.Comparator)\n\tif setComparator.Pointer() != anotherComparator.Pointer() {\n\t\treturn result\n\t}\n\n\tfor it := set.Iterator(); it.Next(); {\n\t\tif !another.Contains(it.Value()) {\n\t\t\tresult.Add(it.Value())\n\t\t}\n\t}\n\n\treturn result\n}\n"
  },
  {
    "path": "sets/treeset/treeset_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage treeset\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestSetNew(t *testing.T) {\n\tset := New[int](2, 1)\n\tif actualValue := set.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tvalues := set.Values()\n\tif actualValue := values[0]; actualValue != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\tif actualValue := values[1]; actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n}\n\nfunc TestSetAdd(t *testing.T) {\n\tset := New[int]()\n\tset.Add()\n\tset.Add(1)\n\tset.Add(2)\n\tset.Add(2, 3)\n\tset.Add()\n\tif actualValue := set.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := set.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\ttestutils.SameElements(t, set.Values(), []int{1, 2, 3})\n}\n\nfunc TestSetContains(t *testing.T) {\n\tset := New[int]()\n\tset.Add(3, 1, 2)\n\tif actualValue := set.Contains(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1, 2, 3); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := set.Contains(1, 2, 3, 4); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n}\n\nfunc TestSetRemove(t *testing.T) {\n\tset := New[int]()\n\tset.Add(3, 1, 2)\n\tset.Remove()\n\tif actualValue := set.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tset.Remove(1)\n\tif actualValue := set.Size(); actualValue != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tset.Remove(3)\n\tset.Remove(3)\n\tset.Remove()\n\tset.Remove(2)\n\tif actualValue := set.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestSetEach(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tset.Each(func(index int, value string) {\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t})\n}\n\nfunc TestSetMap(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tmappedSet := set.Map(func(index int, value string) string {\n\t\treturn \"mapped: \" + value\n\t})\n\tif actualValue, expectedValue := mappedSet.Contains(\"mapped: a\", \"mapped: b\", \"mapped: c\"), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := mappedSet.Contains(\"mapped: a\", \"mapped: b\", \"mapped: x\"), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif mappedSet.Size() != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", mappedSet.Size(), 3)\n\t}\n}\n\nfunc TestSetSelect(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tselectedSet := set.Select(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif actualValue, expectedValue := selectedSet.Contains(\"a\", \"b\"), true; actualValue != expectedValue {\n\t\tfmt.Println(\"A: \", selectedSet.Contains(\"b\"))\n\t\tt.Errorf(\"Got %v (%v) expected %v (%v)\", actualValue, selectedSet.Values(), expectedValue, \"[a b]\")\n\t}\n\tif actualValue, expectedValue := selectedSet.Contains(\"a\", \"b\", \"c\"), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v (%v) expected %v (%v)\", actualValue, selectedSet.Values(), expectedValue, \"[a b]\")\n\t}\n\tif selectedSet.Size() != 2 {\n\t\tt.Errorf(\"Got %v expected %v\", selectedSet.Size(), 3)\n\t}\n}\n\nfunc TestSetAny(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tany := set.Any(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif any != true {\n\t\tt.Errorf(\"Got %v expected %v\", any, true)\n\t}\n\tany = set.Any(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif any != false {\n\t\tt.Errorf(\"Got %v expected %v\", any, false)\n\t}\n}\n\nfunc TestSetAll(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tall := set.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"c\"\n\t})\n\tif all != true {\n\t\tt.Errorf(\"Got %v expected %v\", all, true)\n\t}\n\tall = set.All(func(index int, value string) bool {\n\t\treturn value >= \"a\" && value <= \"b\"\n\t})\n\tif all != false {\n\t\tt.Errorf(\"Got %v expected %v\", all, false)\n\t}\n}\n\nfunc TestSetFind(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tfoundIndex, foundValue := set.Find(func(index int, value string) bool {\n\t\treturn value == \"c\"\n\t})\n\tif foundValue != \"c\" || foundIndex != 2 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, \"c\", 2)\n\t}\n\tfoundIndex, foundValue = set.Find(func(index int, value string) bool {\n\t\treturn value == \"x\"\n\t})\n\tif foundValue != \"\" || foundIndex != -1 {\n\t\tt.Errorf(\"Got %v at %v expected %v at %v\", foundValue, foundIndex, nil, nil)\n\t}\n}\n\nfunc TestSetChaining(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n}\n\nfunc TestSetIteratorNextOnEmpty(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t}\n}\n\nfunc TestSetIteratorPrevOnEmpty(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t}\n}\n\nfunc TestSetIteratorNext(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tit := set.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestSetIteratorPrev(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"c\", \"a\", \"b\")\n\tit := set.Iterator()\n\tfor it.Prev() {\n\t}\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestSetIteratorBegin(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\tit.Begin()\n\tset.Add(\"a\", \"b\", \"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestSetIteratorEnd(t *testing.T) {\n\tset := New[string]()\n\tit := set.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\")\n\tit.End()\n\tif index := it.Index(); index != set.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, set.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != set.Size()-1 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, set.Size()-1, \"c\")\n\t}\n}\n\nfunc TestSetIteratorFirst(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\tit := set.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"a\")\n\t}\n}\n\nfunc TestSetIteratorLast(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\tit := set.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"c\")\n\t}\n}\n\nfunc TestSetIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tset := New[string]()\n\t\tit := set.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"xx\", \"yy\")\n\t\tit := set.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := set.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestSetIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tset := New[string]()\n\t\tit := set.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"xx\", \"yy\")\n\t\tit := set.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tset := New[string]()\n\t\tset.Add(\"aa\", \"bb\", \"cc\")\n\t\tit := set.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty set\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestSetSerialization(t *testing.T) {\n\tset := New[string]()\n\tset.Add(\"a\", \"b\", \"c\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue := set.Contains(\"a\", \"b\", \"c\"); actualValue != true {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := set.ToJSON()\n\tassert()\n\n\terr = set.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", set})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"1\",\"2\",\"3\"]`), &set)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n}\n\nfunc TestSetString(t *testing.T) {\n\tc := New[int]()\n\tc.Add(1)\n\tif !strings.HasPrefix(c.String(), \"TreeSet\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc TestSetIntersection(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tintersection := set.Intersection(another)\n\tif actualValue, expectedValue := intersection.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tintersection = set.Intersection(another)\n\n\tif actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := intersection.Contains(\"c\", \"d\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetUnion(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tunion := set.Union(another)\n\tif actualValue, expectedValue := union.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tunion = set.Union(another)\n\n\tif actualValue, expectedValue := union.Size(), 6; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := union.Contains(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc TestSetDifference(t *testing.T) {\n\tset := New[string]()\n\tanother := New[string]()\n\n\tdifference := set.Difference(another)\n\tif actualValue, expectedValue := difference.Size(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tset.Add(\"a\", \"b\", \"c\", \"d\")\n\tanother.Add(\"c\", \"d\", \"e\", \"f\")\n\n\tdifference = set.Difference(another)\n\n\tif actualValue, expectedValue := difference.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := difference.Contains(\"a\", \"b\"); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n}\n\nfunc benchmarkContains(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Contains(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkAdd(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Add(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, set *Set[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tset.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkTreeSetContains100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkTreeSetContains1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkTreeSetContains10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkTreeSetContains100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkContains(b, set, size)\n}\n\nfunc BenchmarkTreeSetAdd100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkTreeSetAdd1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkTreeSetAdd10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkTreeSetAdd100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkAdd(b, set, size)\n}\n\nfunc BenchmarkTreeSetRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkTreeSetRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkTreeSetRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n\nfunc BenchmarkTreeSetRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tset := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tset.Add(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, set, size)\n}\n"
  },
  {
    "path": "stacks/arraystack/arraystack.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package arraystack implements a stack backed by array list.\n//\n// Structure is not thread safe.\n//\n// Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Array\npackage arraystack\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/arraylist\"\n\t\"github.com/emirpasic/gods/v2/stacks\"\n)\n\n// Assert Stack implementation\nvar _ stacks.Stack[int] = (*Stack[int])(nil)\n\n// Stack holds elements in an array-list\ntype Stack[T comparable] struct {\n\tlist *arraylist.List[T]\n}\n\n// New instantiates a new empty stack\nfunc New[T comparable]() *Stack[T] {\n\treturn &Stack[T]{list: arraylist.New[T]()}\n}\n\n// Push adds a value onto the top of the stack\nfunc (stack *Stack[T]) Push(value T) {\n\tstack.list.Add(value)\n}\n\n// Pop removes top element on stack and returns it, or nil if stack is empty.\n// Second return parameter is true, unless the stack was empty and there was nothing to pop.\nfunc (stack *Stack[T]) Pop() (value T, ok bool) {\n\tvalue, ok = stack.list.Get(stack.list.Size() - 1)\n\tstack.list.Remove(stack.list.Size() - 1)\n\treturn\n}\n\n// Peek returns top element on the stack without removing it, or nil if stack is empty.\n// Second return parameter is true, unless the stack was empty and there was nothing to peek.\nfunc (stack *Stack[T]) Peek() (value T, ok bool) {\n\treturn stack.list.Get(stack.list.Size() - 1)\n}\n\n// Empty returns true if stack does not contain any elements.\nfunc (stack *Stack[T]) Empty() bool {\n\treturn stack.list.Empty()\n}\n\n// Size returns number of elements within the stack.\nfunc (stack *Stack[T]) Size() int {\n\treturn stack.list.Size()\n}\n\n// Clear removes all elements from the stack.\nfunc (stack *Stack[T]) Clear() {\n\tstack.list.Clear()\n}\n\n// Values returns all elements in the stack (LIFO order).\nfunc (stack *Stack[T]) Values() []T {\n\tsize := stack.list.Size()\n\telements := make([]T, size, size)\n\tfor i := 1; i <= size; i++ {\n\t\telements[size-i], _ = stack.list.Get(i - 1) // in reverse (LIFO)\n\t}\n\treturn elements\n}\n\n// String returns a string representation of container\nfunc (stack *Stack[T]) String() string {\n\tstr := \"ArrayStack\\n\"\n\tvalues := []string{}\n\tfor _, value := range stack.list.Values() {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (stack *Stack[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < stack.list.Size()\n}\n"
  },
  {
    "path": "stacks/arraystack/arraystack_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraystack\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestStackPush(t *testing.T) {\n\tstack := New[int]()\n\tif actualValue := stack.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\n\tif actualValue := stack.Values(); actualValue[0] != 3 || actualValue[1] != 2 || actualValue[2] != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[3,2,1]\")\n\t}\n\tif actualValue := stack.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := stack.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := stack.Peek(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n}\n\nfunc TestStackPeek(t *testing.T) {\n\tstack := New[int]()\n\tif actualValue, ok := stack.Peek(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\tif actualValue, ok := stack.Peek(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n}\n\nfunc TestStackPop(t *testing.T) {\n\tstack := New[int]()\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\tstack.Pop()\n\tif actualValue, ok := stack.Peek(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := stack.Pop(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := stack.Pop(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\tif actualValue, ok := stack.Pop(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := stack.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := stack.Values(); len(actualValue) != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[]\")\n\t}\n}\n\nfunc TestStackIteratorOnEmpty(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t}\n}\n\nfunc TestStackIteratorNext(t *testing.T) {\n\tstack := New[string]()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\n\tit := stack.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tstack.Clear()\n\tit = stack.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t}\n}\n\nfunc TestStackIteratorPrev(t *testing.T) {\n\tstack := New[string]()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\n\tit := stack.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, 3-count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestStackIteratorBegin(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\tit.Begin()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"c\")\n\t}\n}\n\nfunc TestStackIteratorEnd(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\tit.End()\n\tif index := it.Index(); index != stack.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, stack.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != stack.Size()-1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, stack.Size()-1, \"a\")\n\t}\n}\n\nfunc TestStackIteratorFirst(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"c\")\n\t}\n}\n\nfunc TestStackIteratorLast(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"a\")\n\t}\n}\n\nfunc TestStackIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tstack := New[string]()\n\t\tit := stack.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tstack := New[string]()\n\t\tstack.Push(\"xx\")\n\t\tstack.Push(\"yy\")\n\t\tit := stack.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tstack := New[string]()\n\t\tstack.Push(\"aa\")\n\t\tstack.Push(\"bb\")\n\t\tstack.Push(\"cc\")\n\t\tit := stack.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"aa\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestStackIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\tstack := New[string]()\n\t\tit := stack.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\tstack := New[string]()\n\t\tstack.Push(\"xx\")\n\t\tstack.Push(\"yy\")\n\t\tit := stack.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\tstack := New[string]()\n\t\tstack.Push(\"aa\")\n\t\tstack.Push(\"bb\")\n\t\tstack.Push(\"cc\")\n\t\tit := stack.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"cc\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestStackSerialization(t *testing.T) {\n\tstack := New[string]()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, stack.Values(), []string{\"c\", \"b\", \"a\"})\n\t\tif actualValue, expectedValue := stack.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := stack.ToJSON()\n\tassert()\n\n\terr = stack.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", stack})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &stack)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestStackString(t *testing.T) {\n\tc := New[int]()\n\tc.Push(1)\n\tif !strings.HasPrefix(c.String(), \"ArrayStack\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkPush(b *testing.B, stack *Stack[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tstack.Push(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPop(b *testing.B, stack *Stack[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tstack.Pop()\n\t\t}\n\t}\n}\n\nfunc BenchmarkArrayStackPop100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPop1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPop10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPop100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPush100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tstack := New[int]()\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPush1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPush10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n\nfunc BenchmarkArrayStackPush100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n"
  },
  {
    "path": "stacks/arraystack/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraystack\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\tstack *Stack[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (stack *Stack[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{stack: stack, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.stack.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.stack.withinRange(iterator.index)\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\treturn iterator.stack.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\tvalue, _ := iterator.stack.list.Get(iterator.stack.list.Size() - iterator.index - 1) // in reverse (LIFO)\n\treturn value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.stack.Size()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "stacks/arraystack/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage arraystack\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Stack[int])(nil)\nvar _ containers.JSONDeserializer = (*Stack[int])(nil)\n\n// ToJSON outputs the JSON representation of the stack.\nfunc (stack *Stack[T]) ToJSON() ([]byte, error) {\n\treturn stack.list.ToJSON()\n}\n\n// FromJSON populates the stack from the input JSON representation.\nfunc (stack *Stack[T]) FromJSON(data []byte) error {\n\treturn stack.list.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (stack *Stack[T]) UnmarshalJSON(bytes []byte) error {\n\treturn stack.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (stack *Stack[T]) MarshalJSON() ([]byte, error) {\n\treturn stack.ToJSON()\n}\n"
  },
  {
    "path": "stacks/linkedliststack/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedliststack\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.IteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\tstack *Stack[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (stack *Stack[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{stack: stack, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.stack.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.stack.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\tvalue, _ := iterator.stack.list.Get(iterator.index) // in reverse (LIFO)\n\treturn value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "stacks/linkedliststack/linkedliststack.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package linkedliststack implements a stack backed by a singly-linked list.\n//\n// Structure is not thread safe.\n//\n// Reference:https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Linked_list\npackage linkedliststack\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/singlylinkedlist\"\n\t\"github.com/emirpasic/gods/v2/stacks\"\n)\n\n// Assert Stack implementation\nvar _ stacks.Stack[int] = (*Stack[int])(nil)\n\n// Stack holds elements in a singly-linked-list\ntype Stack[T comparable] struct {\n\tlist *singlylinkedlist.List[T]\n}\n\n// New nnstantiates a new empty stack\nfunc New[T comparable]() *Stack[T] {\n\treturn &Stack[T]{list: singlylinkedlist.New[T]()}\n}\n\n// Push adds a value onto the top of the stack\nfunc (stack *Stack[T]) Push(value T) {\n\tstack.list.Prepend(value)\n}\n\n// Pop removes top element on stack and returns it, or nil if stack is empty.\n// Second return parameter is true, unless the stack was empty and there was nothing to pop.\nfunc (stack *Stack[T]) Pop() (value T, ok bool) {\n\tvalue, ok = stack.list.Get(0)\n\tstack.list.Remove(0)\n\treturn\n}\n\n// Peek returns top element on the stack without removing it, or nil if stack is empty.\n// Second return parameter is true, unless the stack was empty and there was nothing to peek.\nfunc (stack *Stack[T]) Peek() (value T, ok bool) {\n\treturn stack.list.Get(0)\n}\n\n// Empty returns true if stack does not contain any elements.\nfunc (stack *Stack[T]) Empty() bool {\n\treturn stack.list.Empty()\n}\n\n// Size returns number of elements within the stack.\nfunc (stack *Stack[T]) Size() int {\n\treturn stack.list.Size()\n}\n\n// Clear removes all elements from the stack.\nfunc (stack *Stack[T]) Clear() {\n\tstack.list.Clear()\n}\n\n// Values returns all elements in the stack (LIFO order).\nfunc (stack *Stack[T]) Values() []T {\n\treturn stack.list.Values()\n}\n\n// String returns a string representation of container\nfunc (stack *Stack[T]) String() string {\n\tstr := \"LinkedListStack\\n\"\n\tvalues := []string{}\n\tfor _, value := range stack.list.Values() {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", value))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Check that the index is within bounds of the list\nfunc (stack *Stack[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < stack.list.Size()\n}\n"
  },
  {
    "path": "stacks/linkedliststack/linkedliststack_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedliststack\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/emirpasic/gods/v2/testutils\"\n)\n\nfunc TestStackPush(t *testing.T) {\n\tstack := New[int]()\n\tif actualValue := stack.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\n\tif actualValue := stack.Values(); actualValue[0] != 3 || actualValue[1] != 2 || actualValue[2] != 1 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[3,2,1]\")\n\t}\n\tif actualValue := stack.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := stack.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := stack.Peek(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n}\n\nfunc TestStackPeek(t *testing.T) {\n\tstack := New[int]()\n\tif actualValue, ok := stack.Peek(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\tif actualValue, ok := stack.Peek(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n}\n\nfunc TestStackPop(t *testing.T) {\n\tstack := New[int]()\n\tstack.Push(1)\n\tstack.Push(2)\n\tstack.Push(3)\n\tstack.Pop()\n\tif actualValue, ok := stack.Peek(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := stack.Pop(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := stack.Pop(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n\tif actualValue, ok := stack.Pop(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := stack.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := stack.Values(); len(actualValue) != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[]\")\n\t}\n}\n\nfunc TestStackIterator(t *testing.T) {\n\tstack := New[string]()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\n\t// Iterator\n\tit := stack.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, \"c\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, \"b\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, \"a\"; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tstack.Clear()\n\tit = stack.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t}\n}\n\nfunc TestStackIteratorBegin(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\tit.Begin()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"c\")\n\t}\n}\n\nfunc TestStackIteratorFirst(t *testing.T) {\n\tstack := New[string]()\n\tit := stack.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"c\")\n\t}\n}\n\nfunc TestStackIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\tstack := New[string]()\n\t\tit := stack.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\tstack := New[string]()\n\t\tstack.Push(\"xx\")\n\t\tstack.Push(\"yy\")\n\t\tit := stack.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\tstack := New[string]()\n\t\tstack.Push(\"aa\")\n\t\tstack.Push(\"bb\")\n\t\tstack.Push(\"cc\")\n\t\tit := stack.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty stack\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"aa\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestStackSerialization(t *testing.T) {\n\tstack := New[string]()\n\tstack.Push(\"a\")\n\tstack.Push(\"b\")\n\tstack.Push(\"c\")\n\n\tvar err error\n\tassert := func() {\n\t\ttestutils.SameElements(t, stack.Values(), []string{\"c\", \"b\", \"a\"})\n\t\tif actualValue, expectedValue := stack.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := stack.ToJSON()\n\tassert()\n\n\terr = stack.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", stack})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\terr = json.Unmarshal([]byte(`[\"a\",\"b\",\"c\"]`), &stack)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tassert()\n}\n\nfunc TestStackString(t *testing.T) {\n\tc := New[int]()\n\tc.Push(1)\n\tif !strings.HasPrefix(c.String(), \"LinkedListStack\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkPush(b *testing.B, stack *Stack[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tstack.Push(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPop(b *testing.B, stack *Stack[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\tstack.Pop()\n\t\t}\n\t}\n}\n\nfunc BenchmarkLinkedListStackPop100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPop1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPop10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPop100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPush100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\tstack := New[int]()\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPush1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPush10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n\nfunc BenchmarkLinkedListStackPush100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\tstack := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\tstack.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, stack, size)\n}\n"
  },
  {
    "path": "stacks/linkedliststack/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage linkedliststack\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Stack[int])(nil)\nvar _ containers.JSONDeserializer = (*Stack[int])(nil)\n\n// ToJSON outputs the JSON representation of the stack.\nfunc (stack *Stack[T]) ToJSON() ([]byte, error) {\n\treturn stack.list.ToJSON()\n}\n\n// FromJSON populates the stack from the input JSON representation.\nfunc (stack *Stack[T]) FromJSON(data []byte) error {\n\treturn stack.list.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (stack *Stack[T]) UnmarshalJSON(bytes []byte) error {\n\treturn stack.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (stack *Stack[T]) MarshalJSON() ([]byte, error) {\n\treturn stack.ToJSON()\n}\n"
  },
  {
    "path": "stacks/stacks.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package stacks provides an abstract Stack interface.\n//\n// 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.\n//\n// Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29\npackage stacks\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Stack interface that all stacks implement\ntype Stack[T any] interface {\n\tPush(value T)\n\tPop() (value T, ok bool)\n\tPeek() (value T, ok bool)\n\n\tcontainers.Container[T]\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n"
  },
  {
    "path": "testutils/testutils.go",
    "content": "package testutils\n\nimport \"testing\"\n\nfunc SameElements[T comparable](t *testing.T, actual, expected []T) {\n\tif len(actual) != len(expected) {\n\t\tt.Errorf(\"Got %d expected %d\", len(actual), len(expected))\n\t}\nouter:\n\tfor _, e := range expected {\n\t\tfor _, a := range actual {\n\t\t\tif e == a {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"Did not find expected element %v in %v\", e, actual)\n\t}\n}\n"
  },
  {
    "path": "trees/avltree/avltree.go",
    "content": "// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package avltree implements an AVL balanced binary tree.\n//\n// Structure is not thread safe.\n//\n// References: https://en.wikipedia.org/wiki/AVL_tree\npackage avltree\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/trees\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Tree implementation\nvar _ trees.Tree[int] = (*Tree[string, int])(nil)\n\n// Tree holds elements of the AVL tree.\ntype Tree[K comparable, V any] struct {\n\tRoot       *Node[K, V]         // Root node\n\tComparator utils.Comparator[K] // Key comparator\n\tsize       int                 // Total number of keys in the tree\n}\n\n// Node is a single element within the tree\ntype Node[K comparable, V any] struct {\n\tKey      K\n\tValue    V\n\tParent   *Node[K, V]    // Parent node\n\tChildren [2]*Node[K, V] // Children nodes\n\tb        int8\n}\n\n// New instantiates an AVL tree with the built-in comparator for K\nfunc New[K cmp.Ordered, V any]() *Tree[K, V] {\n\treturn &Tree[K, V]{Comparator: cmp.Compare[K]}\n}\n\n// NewWith instantiates an AVL tree with the custom comparator.\nfunc NewWith[K comparable, V any](comparator utils.Comparator[K]) *Tree[K, V] {\n\treturn &Tree[K, V]{Comparator: comparator}\n}\n\n// Put inserts node into the tree.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Put(key K, value V) {\n\ttree.put(key, value, nil, &tree.Root)\n}\n\n// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.\n// Second return parameter is true if key was found, otherwise false.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Get(key K) (value V, found bool) {\n\tn := tree.GetNode(key)\n\tif n != nil {\n\t\treturn n.Value, true\n\t}\n\treturn value, false\n}\n\n// GetNode searches the node in the tree by key and returns its node or nil if key is not found in tree.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) GetNode(key K) *Node[K, V] {\n\tn := tree.Root\n\tfor n != nil {\n\t\tcmp := tree.Comparator(key, n.Key)\n\t\tswitch {\n\t\tcase cmp == 0:\n\t\t\treturn n\n\t\tcase cmp < 0:\n\t\t\tn = n.Children[0]\n\t\tcase cmp > 0:\n\t\t\tn = n.Children[1]\n\t\t}\n\t}\n\treturn n\n}\n\n// Remove remove the node from the tree by key.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Remove(key K) {\n\ttree.remove(key, &tree.Root)\n}\n\n// Empty returns true if tree does not contain any nodes.\nfunc (tree *Tree[K, V]) Empty() bool {\n\treturn tree.size == 0\n}\n\n// Size returns the number of elements stored in the tree.\nfunc (tree *Tree[K, V]) Size() int {\n\treturn tree.size\n}\n\n// Size returns the number of elements stored in the subtree.\n// Computed dynamically on each call, i.e. the subtree is traversed to count the number of the nodes.\nfunc (n *Node[K, V]) Size() int {\n\tif n == nil {\n\t\treturn 0\n\t}\n\tsize := 1\n\tif n.Children[0] != nil {\n\t\tsize += n.Children[0].Size()\n\t}\n\tif n.Children[1] != nil {\n\t\tsize += n.Children[1].Size()\n\t}\n\treturn size\n}\n\n// Keys returns all keys in-order\nfunc (tree *Tree[K, V]) Keys() []K {\n\tkeys := make([]K, tree.size)\n\tit := tree.Iterator()\n\tfor i := 0; it.Next(); i++ {\n\t\tkeys[i] = it.Key()\n\t}\n\treturn keys\n}\n\n// Values returns all values in-order based on the key.\nfunc (tree *Tree[K, V]) Values() []V {\n\tvalues := make([]V, tree.size)\n\tit := tree.Iterator()\n\tfor i := 0; it.Next(); i++ {\n\t\tvalues[i] = it.Value()\n\t}\n\treturn values\n}\n\n// Left returns the minimum element of the AVL tree\n// or nil if the tree is empty.\nfunc (tree *Tree[K, V]) Left() *Node[K, V] {\n\treturn tree.bottom(0)\n}\n\n// Right returns the maximum element of the AVL tree\n// or nil if the tree is empty.\nfunc (tree *Tree[K, V]) Right() *Node[K, V] {\n\treturn tree.bottom(1)\n}\n\n// Floor Finds floor node of the input key, return the floor node or nil if no floor is found.\n// Second return parameter is true if floor was found, otherwise false.\n//\n// Floor node is defined as the largest node that is smaller than or equal to the given node.\n// A floor node may not be found, either because the tree is empty, or because\n// all nodes in the tree is larger than the given node.\n//\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Floor(key K) (floor *Node[K, V], found bool) {\n\tfound = false\n\tn := tree.Root\n\tfor n != nil {\n\t\tc := tree.Comparator(key, n.Key)\n\t\tswitch {\n\t\tcase c == 0:\n\t\t\treturn n, true\n\t\tcase c < 0:\n\t\t\tn = n.Children[0]\n\t\tcase c > 0:\n\t\t\tfloor, found = n, true\n\t\t\tn = n.Children[1]\n\t\t}\n\t}\n\tif found {\n\t\treturn\n\t}\n\treturn nil, false\n}\n\n// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.\n// Second return parameter is true if ceiling was found, otherwise false.\n//\n// Ceiling node is defined as the smallest node that is larger than or equal to the given node.\n// A ceiling node may not be found, either because the tree is empty, or because\n// all nodes in the tree is smaller than the given node.\n//\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Ceiling(key K) (floor *Node[K, V], found bool) {\n\tfound = false\n\tn := tree.Root\n\tfor n != nil {\n\t\tc := tree.Comparator(key, n.Key)\n\t\tswitch {\n\t\tcase c == 0:\n\t\t\treturn n, true\n\t\tcase c < 0:\n\t\t\tfloor, found = n, true\n\t\t\tn = n.Children[0]\n\t\tcase c > 0:\n\t\t\tn = n.Children[1]\n\t\t}\n\t}\n\tif found {\n\t\treturn\n\t}\n\treturn nil, false\n}\n\n// Clear removes all nodes from the tree.\nfunc (tree *Tree[K, V]) Clear() {\n\ttree.Root = nil\n\ttree.size = 0\n}\n\n// String returns a string representation of container\nfunc (tree *Tree[K, V]) String() string {\n\tstr := \"AVLTree\\n\"\n\tif !tree.Empty() {\n\t\toutput(tree.Root, \"\", true, &str)\n\t}\n\treturn str\n}\n\nfunc (n *Node[K, V]) String() string {\n\treturn fmt.Sprintf(\"%v\", n.Key)\n}\n\nfunc (tree *Tree[K, V]) put(key K, value V, p *Node[K, V], qp **Node[K, V]) bool {\n\tq := *qp\n\tif q == nil {\n\t\ttree.size++\n\t\t*qp = &Node[K, V]{Key: key, Value: value, Parent: p}\n\t\treturn true\n\t}\n\n\tc := tree.Comparator(key, q.Key)\n\tif c == 0 {\n\t\tq.Key = key\n\t\tq.Value = value\n\t\treturn false\n\t}\n\n\tif c < 0 {\n\t\tc = -1\n\t} else {\n\t\tc = 1\n\t}\n\ta := (c + 1) / 2\n\tvar fix bool\n\tfix = tree.put(key, value, q, &q.Children[a])\n\tif fix {\n\t\treturn putFix(int8(c), qp)\n\t}\n\treturn false\n}\n\nfunc (tree *Tree[K, V]) remove(key K, qp **Node[K, V]) bool {\n\tq := *qp\n\tif q == nil {\n\t\treturn false\n\t}\n\n\tc := tree.Comparator(key, q.Key)\n\tif c == 0 {\n\t\ttree.size--\n\t\tif q.Children[1] == nil {\n\t\t\tif q.Children[0] != nil {\n\t\t\t\tq.Children[0].Parent = q.Parent\n\t\t\t}\n\t\t\t*qp = q.Children[0]\n\t\t\treturn true\n\t\t}\n\t\tfix := removeMin(&q.Children[1], &q.Key, &q.Value)\n\t\tif fix {\n\t\t\treturn removeFix(-1, qp)\n\t\t}\n\t\treturn false\n\t}\n\n\tif c < 0 {\n\t\tc = -1\n\t} else {\n\t\tc = 1\n\t}\n\ta := (c + 1) / 2\n\tfix := tree.remove(key, &q.Children[a])\n\tif fix {\n\t\treturn removeFix(int8(-c), qp)\n\t}\n\treturn false\n}\n\nfunc removeMin[K comparable, V any](qp **Node[K, V], minKey *K, minVal *V) bool {\n\tq := *qp\n\tif q.Children[0] == nil {\n\t\t*minKey = q.Key\n\t\t*minVal = q.Value\n\t\tif q.Children[1] != nil {\n\t\t\tq.Children[1].Parent = q.Parent\n\t\t}\n\t\t*qp = q.Children[1]\n\t\treturn true\n\t}\n\tfix := removeMin(&q.Children[0], minKey, minVal)\n\tif fix {\n\t\treturn removeFix(1, qp)\n\t}\n\treturn false\n}\n\nfunc putFix[K comparable, V any](c int8, t **Node[K, V]) bool {\n\ts := *t\n\tif s.b == 0 {\n\t\ts.b = c\n\t\treturn true\n\t}\n\n\tif s.b == -c {\n\t\ts.b = 0\n\t\treturn false\n\t}\n\n\tif s.Children[(c+1)/2].b == c {\n\t\ts = singlerot(c, s)\n\t} else {\n\t\ts = doublerot(c, s)\n\t}\n\t*t = s\n\treturn false\n}\n\nfunc removeFix[K comparable, V any](c int8, t **Node[K, V]) bool {\n\ts := *t\n\tif s.b == 0 {\n\t\ts.b = c\n\t\treturn false\n\t}\n\n\tif s.b == -c {\n\t\ts.b = 0\n\t\treturn true\n\t}\n\n\ta := (c + 1) / 2\n\tif s.Children[a].b == 0 {\n\t\ts = rotate(c, s)\n\t\ts.b = -c\n\t\t*t = s\n\t\treturn false\n\t}\n\n\tif s.Children[a].b == c {\n\t\ts = singlerot(c, s)\n\t} else {\n\t\ts = doublerot(c, s)\n\t}\n\t*t = s\n\treturn true\n}\n\nfunc singlerot[K comparable, V any](c int8, s *Node[K, V]) *Node[K, V] {\n\ts.b = 0\n\ts = rotate(c, s)\n\ts.b = 0\n\treturn s\n}\n\nfunc doublerot[K comparable, V any](c int8, s *Node[K, V]) *Node[K, V] {\n\ta := (c + 1) / 2\n\tr := s.Children[a]\n\ts.Children[a] = rotate(-c, s.Children[a])\n\tp := rotate(c, s)\n\n\tswitch {\n\tdefault:\n\t\ts.b = 0\n\t\tr.b = 0\n\tcase p.b == c:\n\t\ts.b = -c\n\t\tr.b = 0\n\tcase p.b == -c:\n\t\ts.b = 0\n\t\tr.b = c\n\t}\n\n\tp.b = 0\n\treturn p\n}\n\nfunc rotate[K comparable, V any](c int8, s *Node[K, V]) *Node[K, V] {\n\ta := (c + 1) / 2\n\tr := s.Children[a]\n\ts.Children[a] = r.Children[a^1]\n\tif s.Children[a] != nil {\n\t\ts.Children[a].Parent = s\n\t}\n\tr.Children[a^1] = s\n\tr.Parent = s.Parent\n\ts.Parent = r\n\treturn r\n}\n\nfunc (tree *Tree[K, V]) bottom(d int) *Node[K, V] {\n\tn := tree.Root\n\tif n == nil {\n\t\treturn nil\n\t}\n\n\tfor c := n.Children[d]; c != nil; c = n.Children[d] {\n\t\tn = c\n\t}\n\treturn n\n}\n\n// Prev returns the previous element in an inorder\n// walk of the AVL tree.\nfunc (n *Node[K, V]) Prev() *Node[K, V] {\n\treturn n.walk1(0)\n}\n\n// Next returns the next element in an inorder\n// walk of the AVL tree.\nfunc (n *Node[K, V]) Next() *Node[K, V] {\n\treturn n.walk1(1)\n}\n\nfunc (n *Node[K, V]) walk1(a int) *Node[K, V] {\n\tif n == nil {\n\t\treturn nil\n\t}\n\n\tif n.Children[a] != nil {\n\t\tn = n.Children[a]\n\t\tfor n.Children[a^1] != nil {\n\t\t\tn = n.Children[a^1]\n\t\t}\n\t\treturn n\n\t}\n\n\tp := n.Parent\n\tfor p != nil && p.Children[a] == n {\n\t\tn = p\n\t\tp = p.Parent\n\t}\n\treturn p\n}\n\nfunc output[K comparable, V any](node *Node[K, V], prefix string, isTail bool, str *string) {\n\tif node.Children[1] != nil {\n\t\tnewPrefix := prefix\n\t\tif isTail {\n\t\t\tnewPrefix += \"│   \"\n\t\t} else {\n\t\t\tnewPrefix += \"    \"\n\t\t}\n\t\toutput(node.Children[1], newPrefix, false, str)\n\t}\n\t*str += prefix\n\tif isTail {\n\t\t*str += \"└── \"\n\t} else {\n\t\t*str += \"┌── \"\n\t}\n\t*str += node.String() + \"\\n\"\n\tif node.Children[0] != nil {\n\t\tnewPrefix := prefix\n\t\tif isTail {\n\t\t\tnewPrefix += \"    \"\n\t\t} else {\n\t\t\tnewPrefix += \"│   \"\n\t\t}\n\t\toutput(node.Children[0], newPrefix, true, str)\n\t}\n}\n"
  },
  {
    "path": "trees/avltree/avltree_test.go",
    "content": "// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage avltree\n\nimport (\n\t\"encoding/json\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestAVLTreeGet(t *testing.T) {\n\ttree := New[int, string]()\n\n\tif actualValue := tree.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\n\tif actualValue := tree.GetNode(2).Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\t//\n\t//  AVLTree\n\t//  │       ┌── 6\n\t//  │   ┌── 5\n\t//  └── 4\n\t//      │   ┌── 3\n\t//      └── 2\n\t//          └── 1\n\n\tif actualValue := tree.Size(); actualValue != 6 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 6)\n\t}\n\n\tif actualValue := tree.GetNode(2).Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\n\tif actualValue := tree.GetNode(4).Size(); actualValue != 6 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 6)\n\t}\n\n\tif actualValue := tree.GetNode(7).Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestAVLTreePut(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\n\tif actualValue := tree.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\tif actualValue, expectedValue := tree.Keys(), []int{1, 2, 3, 4, 5, 6, 7}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := tree.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestAVLTreeRemove(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\n\ttree.Remove(5)\n\ttree.Remove(6)\n\ttree.Remove(7)\n\ttree.Remove(8)\n\ttree.Remove(5)\n\n\tif actualValue, expectedValue := tree.Keys(), []int{1, 2, 3, 4}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{\"a\", \"b\", \"c\", \"d\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := tree.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := tree.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\ttree.Remove(1)\n\ttree.Remove(4)\n\ttree.Remove(2)\n\ttree.Remove(3)\n\ttree.Remove(2)\n\ttree.Remove(2)\n\n\tif actualValue, expectedValue := tree.Keys(), []int{}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 {\n\t\tt.Errorf(\"Got %v expected %v\", empty, true)\n\t}\n\n}\n\nfunc TestAVLTreeLeftAndRight(t *testing.T) {\n\ttree := New[int, string]()\n\n\tif actualValue := tree.Left(); actualValue != nil {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := tree.Right(); actualValue != nil {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\n\ttree.Put(1, \"a\")\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\") // overwrite\n\ttree.Put(2, \"b\")\n\n\tif actualValue, expectedValue := tree.Left().Key, 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Left().Value, \"x\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tif actualValue, expectedValue := tree.Right().Key, 7; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Right().Value, \"g\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeCeilingAndFloor(t *testing.T) {\n\ttree := New[int, string]()\n\n\tif node, found := tree.Floor(0); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n\tif node, found := tree.Ceiling(0); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\n\tif node, found := tree.Floor(4); node.Key != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", node.Key, 4)\n\t}\n\tif node, found := tree.Floor(0); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n\n\tif node, found := tree.Ceiling(4); node.Key != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", node.Key, 4)\n\t}\n\tif node, found := tree.Ceiling(8); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n}\n\nfunc TestAVLTreeIteratorNextOnEmpty(t *testing.T) {\n\ttree := New[int, string]()\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t}\n}\n\nfunc TestAVLTreeIteratorPrevOnEmpty(t *testing.T) {\n\ttree := New[int, string]()\n\tit := tree.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t}\n}\n\nfunc TestAVLTreeIterator1Next(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\t// │   ┌── 7\n\t// └── 6\n\t//     │   ┌── 5\n\t//     └── 4\n\t//         │   ┌── 3\n\t//         └── 2\n\t//             └── 1\n\tit := tree.Iterator()\n\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator1Prev(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\t// │   ┌── 7\n\t// └── 6\n\t//     │   ┌── 5\n\t//     └── 4\n\t//         │   ┌── 3\n\t//         └── 2\n\t//             └── 1\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator2Next(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator2Prev(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator3Next(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(1, \"a\")\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator3Prev(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(1, \"a\")\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator4Next(t *testing.T) {\n\ttree := New[int, int]()\n\ttree.Put(13, 5)\n\ttree.Put(8, 3)\n\ttree.Put(17, 7)\n\ttree.Put(1, 1)\n\ttree.Put(11, 4)\n\ttree.Put(15, 6)\n\ttree.Put(25, 9)\n\ttree.Put(6, 2)\n\ttree.Put(22, 8)\n\ttree.Put(27, 10)\n\t// │           ┌── 27\n\t// │       ┌── 25\n\t// │       │   └── 22\n\t// │   ┌── 17\n\t// │   │   └── 15\n\t// └── 13\n\t//     │   ┌── 11\n\t//     └── 8\n\t//         │   ┌── 6\n\t//         └── 1\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tvalue := it.Value()\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIterator4Prev(t *testing.T) {\n\ttree := New[int, int]()\n\ttree.Put(13, 5)\n\ttree.Put(8, 3)\n\ttree.Put(17, 7)\n\ttree.Put(1, 1)\n\ttree.Put(11, 4)\n\ttree.Put(15, 6)\n\ttree.Put(25, 9)\n\ttree.Put(6, 2)\n\ttree.Put(22, 8)\n\ttree.Put(27, 10)\n\t// │           ┌── 27\n\t// │       ┌── 25\n\t// │       │   └── 22\n\t// │   ┌── 17\n\t// │   │   └── 15\n\t// └── 13\n\t//     │   ┌── 11\n\t//     └── 8\n\t//         │   ┌── 6\n\t//         └── 1\n\tit := tree.Iterator()\n\tcount := tree.Size()\n\tfor it.Next() {\n\t}\n\tfor it.Prev() {\n\t\tvalue := it.Value()\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcount--\n\t}\n\tif actualValue, expectedValue := count, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeIteratorBegin(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\n\tif it.Key() != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", it.Key(), 0)\n\t}\n\n\tit.Begin()\n\n\tif it.Key() != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", it.Key(), 0)\n\t}\n\n\tfor it.Next() {\n\t}\n\n\tit.Begin()\n\n\tif it.Key() != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", it.Key(), 0)\n\t}\n\n\tit.Next()\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestAVLTreeIteratorEnd(t *testing.T) {\n\ttree := New[int, string]()\n\tit := tree.Iterator()\n\n\tif it.Key() != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", it.Key(), 0)\n\t}\n\n\tit.End()\n\tif it.Key() != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", it.Key(), 0)\n\t}\n\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit.End()\n\tif it.Key() != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", it.Key(), 0)\n\t}\n\n\tit.Prev()\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestAVLTreeIteratorFirst(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestAVLTreeIteratorLast(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestAVLTreeIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\ttree := New[int, string]()\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(0, \"xx\")\n\t\ttree.Put(1, \"yy\")\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(2, \"cc\")\n\t\ttree.Put(0, \"aa\")\n\t\ttree.Put(1, \"bb\")\n\t\tit := tree.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestAVLTreeIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\ttree := New[int, string]()\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(0, \"xx\")\n\t\ttree.Put(1, \"yy\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(2, \"cc\")\n\t\ttree.Put(0, \"aa\")\n\t\ttree.Put(1, \"bb\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestAVLTreeSerialization(t *testing.T) {\n\ttree := New[string, string]()\n\ttree.Put(\"c\", \"3\")\n\ttree.Put(\"b\", \"2\")\n\ttree.Put(\"a\", \"1\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := tree.Keys(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := tree.Values(), []string{\"1\", \"2\", \"3\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := tree.ToJSON()\n\tassert()\n\n\terr = tree.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", tree})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\tintTree := New[string, int]()\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), intTree)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tif actualValue, expectedValue := intTree.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := intTree.Keys(), []string{\"a\", \"b\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := intTree.Values(), []int{1, 2}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestAVLTreeString(t *testing.T) {\n\tc := New[int, int]()\n\tc.Put(1, 1)\n\tc.Put(2, 1)\n\tc.Put(3, 1)\n\tc.Put(4, 1)\n\tc.Put(5, 1)\n\tc.Put(6, 1)\n\tc.Put(7, 1)\n\tc.Put(8, 1)\n\n\tif !strings.HasPrefix(c.String(), \"AVLTree\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Put(n, struct{}{})\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkAVLTreeGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkAVLTreePut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}]()\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkAVLTreePut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkAVLTreePut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkAVLTreePut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkAVLTreeRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n"
  },
  {
    "path": "trees/avltree/iterator.go",
    "content": "// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage avltree\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithKey[string, int] = (*Iterator[string, int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[K comparable, V any] struct {\n\ttree     *Tree[K, V]\n\tnode     *Node[K, V]\n\tposition position\n}\n\ntype position byte\n\nconst (\n\tbegin, between, end position = 0, 1, 2\n)\n\n// Iterator returns a stateful iterator whose elements are key/value pairs.\nfunc (tree *Tree[K, V]) Iterator() *Iterator[K, V] {\n\treturn &Iterator[K, V]{tree: tree, node: nil, position: begin}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Next() bool {\n\tswitch iterator.position {\n\tcase begin:\n\t\titerator.position = between\n\t\titerator.node = iterator.tree.Left()\n\tcase between:\n\t\titerator.node = iterator.node.Next()\n\t}\n\n\tif iterator.node == nil {\n\t\titerator.position = end\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Prev moves the iterator to the next element and returns true if there was a previous element in the container.\n// If Prev() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Prev() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Prev() bool {\n\tswitch iterator.position {\n\tcase end:\n\t\titerator.position = between\n\t\titerator.node = iterator.tree.Right()\n\tcase between:\n\t\titerator.node = iterator.node.Prev()\n\t}\n\n\tif iterator.node == nil {\n\t\titerator.position = begin\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Value() (v V) {\n\tif iterator.node == nil {\n\t\treturn v\n\t}\n\treturn iterator.node.Value\n}\n\n// Key returns the current element's key.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Key() (k K) {\n\tif iterator.node == nil {\n\t\treturn k\n\t}\n\treturn iterator.node.Key\n}\n\n// Node returns the current element's node.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Node() *Node[K, V] {\n\treturn iterator.node\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[K, V]) Begin() {\n\titerator.node = nil\n\titerator.position = begin\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[K, V]) End() {\n\titerator.node = nil\n\titerator.position = end\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator\nfunc (iterator *Iterator[K, V]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) NextTo(f func(key K, value V) bool) bool {\n\tfor iterator.Next() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) PrevTo(f func(key K, value V) bool) bool {\n\tfor iterator.Prev() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "trees/avltree/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage avltree\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Tree[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Tree[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the tree.\nfunc (tree *Tree[K, V]) ToJSON() ([]byte, error) {\n\telements := make(map[K]V)\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t\telements[it.Key()] = it.Value()\n\t}\n\treturn json.Marshal(&elements)\n}\n\n// FromJSON populates the tree from the input JSON representation.\nfunc (tree *Tree[K, V]) FromJSON(data []byte) error {\n\telements := make(map[K]V)\n\terr := json.Unmarshal(data, &elements)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttree.Clear()\n\tfor key, value := range elements {\n\t\ttree.Put(key, value)\n\t}\n\n\treturn nil\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (tree *Tree[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn tree.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (tree *Tree[K, V]) MarshalJSON() ([]byte, error) {\n\treturn tree.ToJSON()\n}\n"
  },
  {
    "path": "trees/binaryheap/binaryheap.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package binaryheap implements a binary heap backed by array list.\n//\n// Comparator defines this heap as either min or max heap.\n//\n// Structure is not thread safe.\n//\n// References: http://en.wikipedia.org/wiki/Binary_heap\npackage binaryheap\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/lists/arraylist\"\n\t\"github.com/emirpasic/gods/v2/trees\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Tree implementation\nvar _ trees.Tree[int] = (*Heap[int])(nil)\n\n// Heap holds elements in an array-list\ntype Heap[T comparable] struct {\n\tlist       *arraylist.List[T]\n\tComparator utils.Comparator[T]\n}\n\n// New instantiates a new empty heap tree with the built-in comparator for T\nfunc New[T cmp.Ordered]() *Heap[T] {\n\treturn &Heap[T]{list: arraylist.New[T](), Comparator: cmp.Compare[T]}\n}\n\n// NewWith instantiates a new empty heap tree with the custom comparator.\nfunc NewWith[T comparable](comparator utils.Comparator[T]) *Heap[T] {\n\treturn &Heap[T]{list: arraylist.New[T](), Comparator: comparator}\n}\n\n// Push adds a value onto the heap and bubbles it up accordingly.\nfunc (heap *Heap[T]) Push(values ...T) {\n\tif len(values) == 1 {\n\t\theap.list.Add(values[0])\n\t\theap.bubbleUp()\n\t} else {\n\t\t// Reference: https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap\n\t\tfor _, value := range values {\n\t\t\theap.list.Add(value)\n\t\t}\n\t\tsize := heap.list.Size()/2 + 1\n\t\tfor i := size; i >= 0; i-- {\n\t\t\theap.bubbleDownIndex(i)\n\t\t}\n\t}\n}\n\n// Pop removes top element on heap and returns it, or nil if heap is empty.\n// Second return parameter is true, unless the heap was empty and there was nothing to pop.\nfunc (heap *Heap[T]) Pop() (value T, ok bool) {\n\tvalue, ok = heap.list.Get(0)\n\tif !ok {\n\t\treturn\n\t}\n\tlastIndex := heap.list.Size() - 1\n\theap.list.Swap(0, lastIndex)\n\theap.list.Remove(lastIndex)\n\theap.bubbleDown()\n\treturn\n}\n\n// Peek returns top element on the heap without removing it, or nil if heap is empty.\n// Second return parameter is true, unless the heap was empty and there was nothing to peek.\nfunc (heap *Heap[T]) Peek() (value T, ok bool) {\n\treturn heap.list.Get(0)\n}\n\n// Empty returns true if heap does not contain any elements.\nfunc (heap *Heap[T]) Empty() bool {\n\treturn heap.list.Empty()\n}\n\n// Size returns number of elements within the heap.\nfunc (heap *Heap[T]) Size() int {\n\treturn heap.list.Size()\n}\n\n// Clear removes all elements from the heap.\nfunc (heap *Heap[T]) Clear() {\n\theap.list.Clear()\n}\n\n// Values returns all elements in the heap.\nfunc (heap *Heap[T]) Values() []T {\n\tvalues := make([]T, heap.list.Size(), heap.list.Size())\n\tfor it := heap.Iterator(); it.Next(); {\n\t\tvalues[it.Index()] = it.Value()\n\t}\n\treturn values\n}\n\n// String returns a string representation of container\nfunc (heap *Heap[T]) String() string {\n\tstr := \"BinaryHeap\\n\"\n\tvalues := []string{}\n\tfor it := heap.Iterator(); it.Next(); {\n\t\tvalues = append(values, fmt.Sprintf(\"%v\", it.Value()))\n\t}\n\tstr += strings.Join(values, \", \")\n\treturn str\n}\n\n// Performs the \"bubble down\" operation. This is to place the element that is at the root\n// of the heap in its correct place so that the heap maintains the min/max-heap order property.\nfunc (heap *Heap[T]) bubbleDown() {\n\theap.bubbleDownIndex(0)\n}\n\n// Performs the \"bubble down\" operation. This is to place the element that is at the index\n// of the heap in its correct place so that the heap maintains the min/max-heap order property.\nfunc (heap *Heap[T]) bubbleDownIndex(index int) {\n\tsize := heap.list.Size()\n\tfor leftIndex := index<<1 + 1; leftIndex < size; leftIndex = index<<1 + 1 {\n\t\trightIndex := index<<1 + 2\n\t\tsmallerIndex := leftIndex\n\t\tleftValue, _ := heap.list.Get(leftIndex)\n\t\trightValue, _ := heap.list.Get(rightIndex)\n\t\tif rightIndex < size && heap.Comparator(leftValue, rightValue) > 0 {\n\t\t\tsmallerIndex = rightIndex\n\t\t}\n\t\tindexValue, _ := heap.list.Get(index)\n\t\tsmallerValue, _ := heap.list.Get(smallerIndex)\n\t\tif heap.Comparator(indexValue, smallerValue) > 0 {\n\t\t\theap.list.Swap(index, smallerIndex)\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t\tindex = smallerIndex\n\t}\n}\n\n// Performs the \"bubble up\" operation. This is to place a newly inserted\n// element (i.e. last element in the list) in its correct place so that\n// the heap maintains the min/max-heap order property.\nfunc (heap *Heap[T]) bubbleUp() {\n\tindex := heap.list.Size() - 1\n\tfor parentIndex := (index - 1) >> 1; index > 0; parentIndex = (index - 1) >> 1 {\n\t\tindexValue, _ := heap.list.Get(index)\n\t\tparentValue, _ := heap.list.Get(parentIndex)\n\t\tif heap.Comparator(parentValue, indexValue) <= 0 {\n\t\t\tbreak\n\t\t}\n\t\theap.list.Swap(index, parentIndex)\n\t\tindex = parentIndex\n\t}\n}\n\n// Check that the index is within bounds of the list\nfunc (heap *Heap[T]) withinRange(index int) bool {\n\treturn index >= 0 && index < heap.list.Size()\n}\n"
  },
  {
    "path": "trees/binaryheap/binaryheap_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage binaryheap\n\nimport (\n\t\"encoding/json\"\n\t\"math/rand\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestBinaryHeapPush(t *testing.T) {\n\theap := New[int]()\n\n\tif actualValue := heap.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\theap.Push(3)\n\theap.Push(2)\n\theap.Push(1)\n\n\tif actualValue, expectedValue := heap.Values(), []int{1, 2, 3}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := heap.Empty(); actualValue != false {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, false)\n\t}\n\tif actualValue := heap.Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := heap.Peek(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestBinaryHeapPushBulk(t *testing.T) {\n\theap := New[int]()\n\n\theap.Push(15, 20, 3, 1, 2)\n\n\tif actualValue, expectedValue := heap.Values(), []int{1, 2, 3, 15, 20}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, ok := heap.Pop(); actualValue != 1 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 1)\n\t}\n}\n\nfunc TestBinaryHeapPop(t *testing.T) {\n\theap := New[int]()\n\n\tif actualValue := heap.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\n\theap.Push(3)\n\theap.Push(2)\n\theap.Push(1)\n\theap.Pop()\n\n\tif actualValue, ok := heap.Peek(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := heap.Pop(); actualValue != 2 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 2)\n\t}\n\tif actualValue, ok := heap.Pop(); actualValue != 3 || !ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\tif actualValue, ok := heap.Pop(); actualValue != 0 || ok {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := heap.Empty(); actualValue != true {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, true)\n\t}\n\tif actualValue := heap.Values(); len(actualValue) != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"[]\")\n\t}\n}\n\nfunc TestBinaryHeapRandom(t *testing.T) {\n\theap := New[int]()\n\n\trand.Seed(3)\n\tfor i := 0; i < 10000; i++ {\n\t\tr := int(rand.Int31n(30))\n\t\theap.Push(r)\n\t}\n\n\tprev, _ := heap.Pop()\n\tfor !heap.Empty() {\n\t\tcurr, _ := heap.Pop()\n\t\tif prev > curr {\n\t\t\tt.Errorf(\"Heap property invalidated. prev: %v current: %v\", prev, curr)\n\t\t}\n\t\tprev = curr\n\t}\n}\n\nfunc TestBinaryHeapIteratorOnEmpty(t *testing.T) {\n\theap := New[int]()\n\tit := heap.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty heap\")\n\t}\n}\n\nfunc TestBinaryHeapIteratorNext(t *testing.T) {\n\theap := New[int]()\n\theap.Push(3)\n\theap.Push(2)\n\theap.Push(1)\n\n\tit := heap.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, count-1; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBinaryHeapIteratorPrev(t *testing.T) {\n\theap := New[int]()\n\theap.Push(3)\n\theap.Push(2)\n\theap.Push(1)\n\n\tit := heap.Iterator()\n\tfor it.Next() {\n\t}\n\tcount := 0\n\tfor it.Prev() {\n\t\tcount++\n\t\tindex := it.Index()\n\t\tvalue := it.Value()\n\t\tswitch index {\n\t\tcase 0:\n\t\t\tif actualValue, expectedValue := value, 1; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 1:\n\t\t\tif actualValue, expectedValue := value, 2; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tcase 2:\n\t\t\tif actualValue, expectedValue := value, 3; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\tdefault:\n\t\t\tt.Errorf(\"Too many\")\n\t\t}\n\t\tif actualValue, expectedValue := index, 3-count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBinaryHeapIteratorBegin(t *testing.T) {\n\theap := New[int]()\n\tit := heap.Iterator()\n\tit.Begin()\n\theap.Push(2)\n\theap.Push(3)\n\theap.Push(1)\n\tfor it.Next() {\n\t}\n\tit.Begin()\n\tit.Next()\n\tif index, value := it.Index(), it.Value(); index != 0 || value != 1 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, 1)\n\t}\n}\n\nfunc TestBinaryHeapIteratorEnd(t *testing.T) {\n\theap := New[int]()\n\tit := heap.Iterator()\n\n\tif index := it.Index(); index != -1 {\n\t\tt.Errorf(\"Got %v expected %v\", index, -1)\n\t}\n\n\tit.End()\n\tif index := it.Index(); index != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", index, 0)\n\t}\n\n\theap.Push(3)\n\theap.Push(2)\n\theap.Push(1)\n\tit.End()\n\tif index := it.Index(); index != heap.Size() {\n\t\tt.Errorf(\"Got %v expected %v\", index, heap.Size())\n\t}\n\n\tit.Prev()\n\tif index, value := it.Index(), it.Value(); index != heap.Size()-1 || value != 3 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, heap.Size()-1, 3)\n\t}\n}\n\nfunc TestBinaryHeapIteratorFirst(t *testing.T) {\n\theap := New[int]()\n\tit := heap.Iterator()\n\tif actualValue, expectedValue := it.First(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\theap.Push(3)\n\theap.Push(2)\n\theap.Push(1)\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 0 || value != 1 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, 1)\n\t}\n}\n\nfunc TestBinaryHeapIteratorLast(t *testing.T) {\n\ttree := New[int]()\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\ttree.Push(2)\n\ttree.Push(3)\n\ttree.Push(1)\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif index, value := it.Index(), it.Value(); index != 2 || value != 3 {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, 3)\n\t}\n}\n\nfunc TestBinaryHeapIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\ttree := New[string]()\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Push(\"xx\")\n\t\ttree.Push(\"yy\")\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Push(\"aa\")\n\t\ttree.Push(\"bb\")\n\t\ttree.Push(\"cc\")\n\t\tit := tree.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestBinaryHeapIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\ttree := New[string]()\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Push(\"xx\")\n\t\ttree.Push(\"yy\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\ttree := New[string]()\n\t\ttree.Push(\"aa\")\n\t\ttree.Push(\"bb\")\n\t\ttree.Push(\"cc\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty list\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Index(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestBinaryHeapSerialization(t *testing.T) {\n\theap := New[string]()\n\n\theap.Push(\"c\")\n\theap.Push(\"b\")\n\theap.Push(\"a\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := heap.Values(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue := heap.Size(); actualValue != 3 {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t\t}\n\t\tif actualValue, ok := heap.Peek(); actualValue != \"a\" || !ok {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, \"a\")\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := heap.ToJSON()\n\tassert()\n\n\terr = heap.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", heap})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\tintHeap := New[int]()\n\terr = json.Unmarshal([]byte(`[1,2,3]`), &intHeap)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tif actualValue, expectedValue := intHeap.Values(), []int{1, 2, 3}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeString(t *testing.T) {\n\tc := New[int]()\n\tc.Push(1)\n\tif !strings.HasPrefix(c.String(), \"BinaryHeap\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkPush(b *testing.B, heap *Heap[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\theap.Push(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPop(b *testing.B, heap *Heap[int], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\theap.Pop()\n\t\t}\n\t}\n}\n\nfunc BenchmarkBinaryHeapPop100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPop1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPop10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPop100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPop(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPush100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\theap := New[int]()\n\tb.StartTimer()\n\tbenchmarkPush(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPush1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPush10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, heap, size)\n}\n\nfunc BenchmarkBinaryHeapPush100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\theap := New[int]()\n\tfor n := 0; n < size; n++ {\n\t\theap.Push(n)\n\t}\n\tb.StartTimer()\n\tbenchmarkPush(b, heap, size)\n}\n"
  },
  {
    "path": "trees/binaryheap/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage binaryheap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithIndex[int] = (*Iterator[int])(nil)\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\ntype Iterator[T comparable] struct {\n\theap  *Heap[T]\n\tindex int\n}\n\n// Iterator returns a stateful iterator whose values can be fetched by an index.\nfunc (heap *Heap[T]) Iterator() *Iterator[T] {\n\treturn &Iterator[T]{heap: heap, index: -1}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Next() bool {\n\tif iterator.index < iterator.heap.Size() {\n\t\titerator.index++\n\t}\n\treturn iterator.heap.withinRange(iterator.index)\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Prev() bool {\n\tif iterator.index >= 0 {\n\t\titerator.index--\n\t}\n\treturn iterator.heap.withinRange(iterator.index)\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Value() T {\n\tstart, end := evaluateRange(iterator.index)\n\tif end > iterator.heap.Size() {\n\t\tend = iterator.heap.Size()\n\t}\n\ttmpHeap := NewWith(iterator.heap.Comparator)\n\tfor n := start; n < end; n++ {\n\t\tvalue, _ := iterator.heap.list.Get(n)\n\t\ttmpHeap.Push(value)\n\t}\n\tfor n := 0; n < iterator.index-start; n++ {\n\t\ttmpHeap.Pop()\n\t}\n\tvalue, _ := tmpHeap.Pop()\n\treturn value\n}\n\n// Index returns the current element's index.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[T]) Index() int {\n\treturn iterator.index\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[T]) Begin() {\n\titerator.index = -1\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[T]) End() {\n\titerator.index = iterator.heap.Size()\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) NextTo(f func(index int, value T) bool) bool {\n\tfor iterator.Next() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's index and value can be retrieved by Index() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[T]) PrevTo(f func(index int, value T) bool) bool {\n\tfor iterator.Prev() {\n\t\tindex, value := iterator.Index(), iterator.Value()\n\t\tif f(index, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// numOfBits counts the number of bits of an int\nfunc numOfBits(n int) uint {\n\tvar count uint\n\tfor n != 0 {\n\t\tcount++\n\t\tn >>= 1\n\t}\n\treturn count\n}\n\n// evaluateRange evaluates the index range [start,end) of same level nodes in the heap as the index\nfunc evaluateRange(index int) (start int, end int) {\n\tbits := numOfBits(index+1) - 1\n\tstart = 1<<bits - 1\n\tend = start + 1<<bits\n\treturn\n}\n"
  },
  {
    "path": "trees/binaryheap/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage binaryheap\n\nimport (\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Heap[int])(nil)\nvar _ containers.JSONDeserializer = (*Heap[int])(nil)\n\n// ToJSON outputs the JSON representation of the heap.\nfunc (heap *Heap[T]) ToJSON() ([]byte, error) {\n\treturn heap.list.ToJSON()\n}\n\n// FromJSON populates the heap from the input JSON representation.\nfunc (heap *Heap[T]) FromJSON(data []byte) error {\n\treturn heap.list.FromJSON(data)\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (heap *Heap[T]) UnmarshalJSON(bytes []byte) error {\n\treturn heap.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (heap *Heap[T]) MarshalJSON() ([]byte, error) {\n\treturn heap.ToJSON()\n}\n"
  },
  {
    "path": "trees/btree/btree.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package btree implements a B tree.\n//\n// According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties:\n// - Every node has at most m children.\n// - Every non-leaf node (except root) has at least ⌈m/2⌉ children.\n// - The root has at least two children if it is not a leaf node.\n// - A non-leaf node with k children contains k−1 keys.\n// - All leaves appear in the same level\n//\n// Structure is not thread safe.\n//\n// References: https://en.wikipedia.org/wiki/B-tree\npackage btree\n\nimport (\n\t\"bytes\"\n\t\"cmp\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/emirpasic/gods/v2/trees\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Tree implementation\nvar _ trees.Tree[int] = (*Tree[string, int])(nil)\n\n// Tree holds elements of the B-tree\ntype Tree[K comparable, V any] struct {\n\tRoot       *Node[K, V]         // Root node\n\tComparator utils.Comparator[K] // Key comparator\n\tsize       int                 // Total number of keys in the tree\n\tm          int                 // order (maximum number of children)\n}\n\n// Node is a single element within the tree\ntype Node[K comparable, V any] struct {\n\tParent   *Node[K, V]\n\tEntries  []*Entry[K, V] // Contained keys in node\n\tChildren []*Node[K, V]  // Children nodes\n}\n\n// Entry represents the key-value pair contained within nodes\ntype Entry[K comparable, V any] struct {\n\tKey   K\n\tValue V\n}\n\n// New instantiates a B-tree with the order (maximum number of children) and the built-in comparator for K\nfunc New[K cmp.Ordered, V any](order int) *Tree[K, V] {\n\treturn NewWith[K, V](order, cmp.Compare[K])\n}\n\n// NewWith instantiates a B-tree with the order (maximum number of children) and a custom key comparator.\nfunc NewWith[K comparable, V any](order int, comparator utils.Comparator[K]) *Tree[K, V] {\n\tif order < 3 {\n\t\tpanic(\"Invalid order, should be at least 3\")\n\t}\n\treturn &Tree[K, V]{m: order, Comparator: comparator}\n}\n\n// Put inserts key-value pair node into the tree.\n// If key already exists, then its value is updated with the new value.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Put(key K, value V) {\n\tentry := &Entry[K, V]{Key: key, Value: value}\n\n\tif tree.Root == nil {\n\t\ttree.Root = &Node[K, V]{Entries: []*Entry[K, V]{entry}, Children: []*Node[K, V]{}}\n\t\ttree.size++\n\t\treturn\n\t}\n\n\tif tree.insert(tree.Root, entry) {\n\t\ttree.size++\n\t}\n}\n\n// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.\n// Second return parameter is true if key was found, otherwise false.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Get(key K) (value V, found bool) {\n\tnode, index, found := tree.searchRecursively(tree.Root, key)\n\tif found {\n\t\treturn node.Entries[index].Value, true\n\t}\n\treturn value, false\n}\n\n// GetNode searches the node in the tree by key and returns its node or nil if key is not found in tree.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) GetNode(key K) *Node[K, V] {\n\tnode, _, _ := tree.searchRecursively(tree.Root, key)\n\treturn node\n}\n\n// Remove remove the node from the tree by key.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Remove(key K) {\n\tnode, index, found := tree.searchRecursively(tree.Root, key)\n\tif found {\n\t\ttree.delete(node, index)\n\t\ttree.size--\n\t}\n}\n\n// Empty returns true if tree does not contain any nodes\nfunc (tree *Tree[K, V]) Empty() bool {\n\treturn tree.size == 0\n}\n\n// Size returns number of nodes in the tree.\nfunc (tree *Tree[K, V]) Size() int {\n\treturn tree.size\n}\n\n// Size returns the number of elements stored in the subtree.\n// Computed dynamically on each call, i.e. the subtree is traversed to count the number of the nodes.\nfunc (node *Node[K, V]) Size() int {\n\tif node == nil {\n\t\treturn 0\n\t}\n\tsize := 1\n\tfor _, child := range node.Children {\n\t\tsize += child.Size()\n\t}\n\treturn size\n}\n\n// Keys returns all keys in-order\nfunc (tree *Tree[K, V]) Keys() []K {\n\tkeys := make([]K, tree.size)\n\tit := tree.Iterator()\n\tfor i := 0; it.Next(); i++ {\n\t\tkeys[i] = it.Key()\n\t}\n\treturn keys\n}\n\n// Values returns all values in-order based on the key.\nfunc (tree *Tree[K, V]) Values() []V {\n\tvalues := make([]V, tree.size)\n\tit := tree.Iterator()\n\tfor i := 0; it.Next(); i++ {\n\t\tvalues[i] = it.Value()\n\t}\n\treturn values\n}\n\n// Clear removes all nodes from the tree.\nfunc (tree *Tree[K, V]) Clear() {\n\ttree.Root = nil\n\ttree.size = 0\n}\n\n// Height returns the height of the tree.\nfunc (tree *Tree[K, V]) Height() int {\n\treturn tree.Root.height()\n}\n\n// Left returns the left-most (min) node or nil if tree is empty.\nfunc (tree *Tree[K, V]) Left() *Node[K, V] {\n\treturn tree.left(tree.Root)\n}\n\n// LeftKey returns the left-most (min) key or nil if tree is empty.\nfunc (tree *Tree[K, V]) LeftKey() interface{} {\n\tif left := tree.Left(); left != nil {\n\t\treturn left.Entries[0].Key\n\t}\n\treturn nil\n}\n\n// LeftValue returns the left-most value or nil if tree is empty.\nfunc (tree *Tree[K, V]) LeftValue() interface{} {\n\tif left := tree.Left(); left != nil {\n\t\treturn left.Entries[0].Value\n\t}\n\treturn nil\n}\n\n// Right returns the right-most (max) node or nil if tree is empty.\nfunc (tree *Tree[K, V]) Right() *Node[K, V] {\n\treturn tree.right(tree.Root)\n}\n\n// RightKey returns the right-most (max) key or nil if tree is empty.\nfunc (tree *Tree[K, V]) RightKey() interface{} {\n\tif right := tree.Right(); right != nil {\n\t\treturn right.Entries[len(right.Entries)-1].Key\n\t}\n\treturn nil\n}\n\n// RightValue returns the right-most value or nil if tree is empty.\nfunc (tree *Tree[K, V]) RightValue() interface{} {\n\tif right := tree.Right(); right != nil {\n\t\treturn right.Entries[len(right.Entries)-1].Value\n\t}\n\treturn nil\n}\n\n// String returns a string representation of container (for debugging purposes)\nfunc (tree *Tree[K, V]) String() string {\n\tvar buffer bytes.Buffer\n\tbuffer.WriteString(\"BTree\\n\")\n\tif !tree.Empty() {\n\t\ttree.output(&buffer, tree.Root, 0)\n\t}\n\treturn buffer.String()\n}\n\nfunc (entry *Entry[K, V]) String() string {\n\treturn fmt.Sprintf(\"%v\", entry.Key)\n}\n\nfunc (tree *Tree[K, V]) output(buffer *bytes.Buffer, node *Node[K, V], level int) {\n\tfor e := 0; e < len(node.Entries)+1; e++ {\n\t\tif e < len(node.Children) {\n\t\t\ttree.output(buffer, node.Children[e], level+1)\n\t\t}\n\t\tif e < len(node.Entries) {\n\t\t\tbuffer.WriteString(strings.Repeat(\"    \", level))\n\t\t\tbuffer.WriteString(fmt.Sprintf(\"%v\", node.Entries[e].Key) + \"\\n\")\n\t\t}\n\t}\n}\n\nfunc (node *Node[K, V]) height() int {\n\theight := 0\n\tfor ; node != nil; node = node.Children[0] {\n\t\theight++\n\t\tif len(node.Children) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn height\n}\n\nfunc (tree *Tree[K, V]) isLeaf(node *Node[K, V]) bool {\n\treturn len(node.Children) == 0\n}\n\nfunc (tree *Tree[K, V]) isFull(node *Node[K, V]) bool {\n\treturn len(node.Entries) == tree.maxEntries()\n}\n\nfunc (tree *Tree[K, V]) shouldSplit(node *Node[K, V]) bool {\n\treturn len(node.Entries) > tree.maxEntries()\n}\n\nfunc (tree *Tree[K, V]) maxChildren() int {\n\treturn tree.m\n}\n\nfunc (tree *Tree[K, V]) minChildren() int {\n\treturn (tree.m + 1) / 2 // ceil(m/2)\n}\n\nfunc (tree *Tree[K, V]) maxEntries() int {\n\treturn tree.maxChildren() - 1\n}\n\nfunc (tree *Tree[K, V]) minEntries() int {\n\treturn tree.minChildren() - 1\n}\n\nfunc (tree *Tree[K, V]) middle() int {\n\treturn (tree.m - 1) / 2 // \"-1\" to favor right nodes to have more keys when splitting\n}\n\n// search searches only within the single node among its entries\nfunc (tree *Tree[K, V]) search(node *Node[K, V], key K) (index int, found bool) {\n\tlow, high := 0, len(node.Entries)-1\n\tvar mid int\n\tfor low <= high {\n\t\tmid = (high + low) / 2\n\t\tcompare := tree.Comparator(key, node.Entries[mid].Key)\n\t\tswitch {\n\t\tcase compare > 0:\n\t\t\tlow = mid + 1\n\t\tcase compare < 0:\n\t\t\thigh = mid - 1\n\t\tcase compare == 0:\n\t\t\treturn mid, true\n\t\t}\n\t}\n\treturn low, false\n}\n\n// searchRecursively searches recursively down the tree starting at the startNode\nfunc (tree *Tree[K, V]) searchRecursively(startNode *Node[K, V], key K) (node *Node[K, V], index int, found bool) {\n\tif tree.Empty() {\n\t\treturn nil, -1, false\n\t}\n\tnode = startNode\n\tfor {\n\t\tindex, found = tree.search(node, key)\n\t\tif found {\n\t\t\treturn node, index, true\n\t\t}\n\t\tif tree.isLeaf(node) {\n\t\t\treturn nil, -1, false\n\t\t}\n\t\tnode = node.Children[index]\n\t}\n}\n\nfunc (tree *Tree[K, V]) insert(node *Node[K, V], entry *Entry[K, V]) (inserted bool) {\n\tif tree.isLeaf(node) {\n\t\treturn tree.insertIntoLeaf(node, entry)\n\t}\n\treturn tree.insertIntoInternal(node, entry)\n}\n\nfunc (tree *Tree[K, V]) insertIntoLeaf(node *Node[K, V], entry *Entry[K, V]) (inserted bool) {\n\tinsertPosition, found := tree.search(node, entry.Key)\n\tif found {\n\t\tnode.Entries[insertPosition] = entry\n\t\treturn false\n\t}\n\t// Insert entry's key in the middle of the node\n\tnode.Entries = append(node.Entries, nil)\n\tcopy(node.Entries[insertPosition+1:], node.Entries[insertPosition:])\n\tnode.Entries[insertPosition] = entry\n\ttree.split(node)\n\treturn true\n}\n\nfunc (tree *Tree[K, V]) insertIntoInternal(node *Node[K, V], entry *Entry[K, V]) (inserted bool) {\n\tinsertPosition, found := tree.search(node, entry.Key)\n\tif found {\n\t\tnode.Entries[insertPosition] = entry\n\t\treturn false\n\t}\n\treturn tree.insert(node.Children[insertPosition], entry)\n}\n\nfunc (tree *Tree[K, V]) split(node *Node[K, V]) {\n\tif !tree.shouldSplit(node) {\n\t\treturn\n\t}\n\n\tif node == tree.Root {\n\t\ttree.splitRoot()\n\t\treturn\n\t}\n\n\ttree.splitNonRoot(node)\n}\n\nfunc (tree *Tree[K, V]) splitNonRoot(node *Node[K, V]) {\n\tmiddle := tree.middle()\n\tparent := node.Parent\n\n\tleft := &Node[K, V]{Entries: append([]*Entry[K, V](nil), node.Entries[:middle]...), Parent: parent}\n\tright := &Node[K, V]{Entries: append([]*Entry[K, V](nil), node.Entries[middle+1:]...), Parent: parent}\n\n\t// Move children from the node to be split into left and right nodes\n\tif !tree.isLeaf(node) {\n\t\tleft.Children = append([]*Node[K, V](nil), node.Children[:middle+1]...)\n\t\tright.Children = append([]*Node[K, V](nil), node.Children[middle+1:]...)\n\t\tsetParent(left.Children, left)\n\t\tsetParent(right.Children, right)\n\t}\n\n\tinsertPosition, _ := tree.search(parent, node.Entries[middle].Key)\n\n\t// Insert middle key into parent\n\tparent.Entries = append(parent.Entries, nil)\n\tcopy(parent.Entries[insertPosition+1:], parent.Entries[insertPosition:])\n\tparent.Entries[insertPosition] = node.Entries[middle]\n\n\t// Set child left of inserted key in parent to the created left node\n\tparent.Children[insertPosition] = left\n\n\t// Set child right of inserted key in parent to the created right node\n\tparent.Children = append(parent.Children, nil)\n\tcopy(parent.Children[insertPosition+2:], parent.Children[insertPosition+1:])\n\tparent.Children[insertPosition+1] = right\n\n\ttree.split(parent)\n}\n\nfunc (tree *Tree[K, V]) splitRoot() {\n\tmiddle := tree.middle()\n\n\tleft := &Node[K, V]{Entries: append([]*Entry[K, V](nil), tree.Root.Entries[:middle]...)}\n\tright := &Node[K, V]{Entries: append([]*Entry[K, V](nil), tree.Root.Entries[middle+1:]...)}\n\n\t// Move children from the node to be split into left and right nodes\n\tif !tree.isLeaf(tree.Root) {\n\t\tleft.Children = append([]*Node[K, V](nil), tree.Root.Children[:middle+1]...)\n\t\tright.Children = append([]*Node[K, V](nil), tree.Root.Children[middle+1:]...)\n\t\tsetParent(left.Children, left)\n\t\tsetParent(right.Children, right)\n\t}\n\n\t// Root is a node with one entry and two children (left and right)\n\tnewRoot := &Node[K, V]{\n\t\tEntries:  []*Entry[K, V]{tree.Root.Entries[middle]},\n\t\tChildren: []*Node[K, V]{left, right},\n\t}\n\n\tleft.Parent = newRoot\n\tright.Parent = newRoot\n\ttree.Root = newRoot\n}\n\nfunc setParent[K comparable, V any](nodes []*Node[K, V], parent *Node[K, V]) {\n\tfor _, node := range nodes {\n\t\tnode.Parent = parent\n\t}\n}\n\nfunc (tree *Tree[K, V]) left(node *Node[K, V]) *Node[K, V] {\n\tif tree.Empty() {\n\t\treturn nil\n\t}\n\tcurrent := node\n\tfor {\n\t\tif tree.isLeaf(current) {\n\t\t\treturn current\n\t\t}\n\t\tcurrent = current.Children[0]\n\t}\n}\n\nfunc (tree *Tree[K, V]) right(node *Node[K, V]) *Node[K, V] {\n\tif tree.Empty() {\n\t\treturn nil\n\t}\n\tcurrent := node\n\tfor {\n\t\tif tree.isLeaf(current) {\n\t\t\treturn current\n\t\t}\n\t\tcurrent = current.Children[len(current.Children)-1]\n\t}\n}\n\n// leftSibling returns the node's left sibling and child index (in parent) if it exists, otherwise (nil,-1)\n// key is any of keys in node (could even be deleted).\nfunc (tree *Tree[K, V]) leftSibling(node *Node[K, V], key K) (*Node[K, V], int) {\n\tif node.Parent != nil {\n\t\tindex, _ := tree.search(node.Parent, key)\n\t\tindex--\n\t\tif index >= 0 && index < len(node.Parent.Children) {\n\t\t\treturn node.Parent.Children[index], index\n\t\t}\n\t}\n\treturn nil, -1\n}\n\n// rightSibling returns the node's right sibling and child index (in parent) if it exists, otherwise (nil,-1)\n// key is any of keys in node (could even be deleted).\nfunc (tree *Tree[K, V]) rightSibling(node *Node[K, V], key K) (*Node[K, V], int) {\n\tif node.Parent != nil {\n\t\tindex, _ := tree.search(node.Parent, key)\n\t\tindex++\n\t\tif index < len(node.Parent.Children) {\n\t\t\treturn node.Parent.Children[index], index\n\t\t}\n\t}\n\treturn nil, -1\n}\n\n// delete deletes an entry in node at entries' index\n// ref.: https://en.wikipedia.org/wiki/B-tree#Deletion\nfunc (tree *Tree[K, V]) delete(node *Node[K, V], index int) {\n\t// deleting from a leaf node\n\tif tree.isLeaf(node) {\n\t\tdeletedKey := node.Entries[index].Key\n\t\ttree.deleteEntry(node, index)\n\t\ttree.rebalance(node, deletedKey)\n\t\tif len(tree.Root.Entries) == 0 {\n\t\t\ttree.Root = nil\n\t\t}\n\t\treturn\n\t}\n\n\t// deleting from an internal node\n\tleftLargestNode := tree.right(node.Children[index]) // largest node in the left sub-tree (assumed to exist)\n\tleftLargestEntryIndex := len(leftLargestNode.Entries) - 1\n\tnode.Entries[index] = leftLargestNode.Entries[leftLargestEntryIndex]\n\tdeletedKey := leftLargestNode.Entries[leftLargestEntryIndex].Key\n\ttree.deleteEntry(leftLargestNode, leftLargestEntryIndex)\n\ttree.rebalance(leftLargestNode, deletedKey)\n}\n\n// rebalance rebalances the tree after deletion if necessary and returns true, otherwise false.\n// Note that we first delete the entry and then call rebalance, thus the passed deleted key as reference.\nfunc (tree *Tree[K, V]) rebalance(node *Node[K, V], deletedKey K) {\n\t// check if rebalancing is needed\n\tif node == nil || len(node.Entries) >= tree.minEntries() {\n\t\treturn\n\t}\n\n\t// try to borrow from left sibling\n\tleftSibling, leftSiblingIndex := tree.leftSibling(node, deletedKey)\n\tif leftSibling != nil && len(leftSibling.Entries) > tree.minEntries() {\n\t\t// rotate right\n\t\tnode.Entries = append([]*Entry[K, V]{node.Parent.Entries[leftSiblingIndex]}, node.Entries...) // prepend parent's separator entry to node's entries\n\t\tnode.Parent.Entries[leftSiblingIndex] = leftSibling.Entries[len(leftSibling.Entries)-1]\n\t\ttree.deleteEntry(leftSibling, len(leftSibling.Entries)-1)\n\t\tif !tree.isLeaf(leftSibling) {\n\t\t\tleftSiblingRightMostChild := leftSibling.Children[len(leftSibling.Children)-1]\n\t\t\tleftSiblingRightMostChild.Parent = node\n\t\t\tnode.Children = append([]*Node[K, V]{leftSiblingRightMostChild}, node.Children...)\n\t\t\ttree.deleteChild(leftSibling, len(leftSibling.Children)-1)\n\t\t}\n\t\treturn\n\t}\n\n\t// try to borrow from right sibling\n\trightSibling, rightSiblingIndex := tree.rightSibling(node, deletedKey)\n\tif rightSibling != nil && len(rightSibling.Entries) > tree.minEntries() {\n\t\t// rotate left\n\t\tnode.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1]) // append parent's separator entry to node's entries\n\t\tnode.Parent.Entries[rightSiblingIndex-1] = rightSibling.Entries[0]\n\t\ttree.deleteEntry(rightSibling, 0)\n\t\tif !tree.isLeaf(rightSibling) {\n\t\t\trightSiblingLeftMostChild := rightSibling.Children[0]\n\t\t\trightSiblingLeftMostChild.Parent = node\n\t\t\tnode.Children = append(node.Children, rightSiblingLeftMostChild)\n\t\t\ttree.deleteChild(rightSibling, 0)\n\t\t}\n\t\treturn\n\t}\n\n\t// merge with siblings\n\tif rightSibling != nil {\n\t\t// merge with right sibling\n\t\tnode.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1])\n\t\tnode.Entries = append(node.Entries, rightSibling.Entries...)\n\t\tdeletedKey = node.Parent.Entries[rightSiblingIndex-1].Key\n\t\ttree.deleteEntry(node.Parent, rightSiblingIndex-1)\n\t\ttree.appendChildren(node.Parent.Children[rightSiblingIndex], node)\n\t\ttree.deleteChild(node.Parent, rightSiblingIndex)\n\t} else if leftSibling != nil {\n\t\t// merge with left sibling\n\t\tentries := append([]*Entry[K, V](nil), leftSibling.Entries...)\n\t\tentries = append(entries, node.Parent.Entries[leftSiblingIndex])\n\t\tnode.Entries = append(entries, node.Entries...)\n\t\tdeletedKey = node.Parent.Entries[leftSiblingIndex].Key\n\t\ttree.deleteEntry(node.Parent, leftSiblingIndex)\n\t\ttree.prependChildren(node.Parent.Children[leftSiblingIndex], node)\n\t\ttree.deleteChild(node.Parent, leftSiblingIndex)\n\t}\n\n\t// make the merged node the root if its parent was the root and the root is empty\n\tif node.Parent == tree.Root && len(tree.Root.Entries) == 0 {\n\t\ttree.Root = node\n\t\tnode.Parent = nil\n\t\treturn\n\t}\n\n\t// parent might underflow, so try to rebalance if necessary\n\ttree.rebalance(node.Parent, deletedKey)\n}\n\nfunc (tree *Tree[K, V]) prependChildren(fromNode *Node[K, V], toNode *Node[K, V]) {\n\tchildren := append([]*Node[K, V](nil), fromNode.Children...)\n\ttoNode.Children = append(children, toNode.Children...)\n\tsetParent(fromNode.Children, toNode)\n}\n\nfunc (tree *Tree[K, V]) appendChildren(fromNode *Node[K, V], toNode *Node[K, V]) {\n\ttoNode.Children = append(toNode.Children, fromNode.Children...)\n\tsetParent(fromNode.Children, toNode)\n}\n\nfunc (tree *Tree[K, V]) deleteEntry(node *Node[K, V], index int) {\n\tcopy(node.Entries[index:], node.Entries[index+1:])\n\tnode.Entries[len(node.Entries)-1] = nil\n\tnode.Entries = node.Entries[:len(node.Entries)-1]\n}\n\nfunc (tree *Tree[K, V]) deleteChild(node *Node[K, V], index int) {\n\tif index >= len(node.Children) {\n\t\treturn\n\t}\n\tcopy(node.Children[index:], node.Children[index+1:])\n\tnode.Children[len(node.Children)-1] = nil\n\tnode.Children = node.Children[:len(node.Children)-1]\n}\n"
  },
  {
    "path": "trees/btree/btree_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage btree\n\nimport (\n\t\"encoding/json\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestBTreeGet1(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\n\ttests := [][]interface{}{\n\t\t{0, \"\", false},\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests {\n\t\tif value, found := tree.Get(test[0].(int)); value != test[1] || found != test[2] {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", value, found, test[1], test[2])\n\t\t}\n\t}\n}\n\nfunc TestBTreeGet2(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(7, \"g\")\n\ttree.Put(9, \"i\")\n\ttree.Put(10, \"j\")\n\ttree.Put(6, \"f\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(5, \"e\")\n\ttree.Put(8, \"h\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\")\n\n\ttests := [][]interface{}{\n\t\t{0, \"\", false},\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"h\", true},\n\t\t{9, \"i\", true},\n\t\t{10, \"j\", true},\n\t\t{11, \"\", false},\n\t}\n\n\tfor _, test := range tests {\n\t\tif value, found := tree.Get(test[0].(int)); value != test[1] || found != test[2] {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", value, found, test[1], test[2])\n\t\t}\n\t}\n}\n\nfunc TestBTreeGet3(t *testing.T) {\n\ttree := New[int, string](3)\n\n\tif actualValue := tree.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\n\tif actualValue := tree.GetNode(2).Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\ttree.Put(7, \"g\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order)\n\n\t// BTree\n\t//         1\n\t//     2\n\t//         3\n\t// 4\n\t//         5\n\t//     6\n\t//         7\n\n\tif actualValue := tree.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\n\tif actualValue := tree.GetNode(2).Size(); actualValue != 3 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 3)\n\t}\n\n\tif actualValue := tree.GetNode(4).Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\n\tif actualValue := tree.GetNode(8).Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestBTreePut1(t *testing.T) {\n\t// https://upload.wikimedia.org/wikipedia/commons/3/33/B_tree_insertion_example.png\n\ttree := New[int, int](3)\n\tassertValidTree(t, tree, 0)\n\n\ttree.Put(1, 0)\n\tassertValidTree(t, tree, 1)\n\tassertValidTreeNode(t, tree.Root, 1, 0, []int{1}, false)\n\n\ttree.Put(2, 1)\n\tassertValidTree(t, tree, 2)\n\tassertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false)\n\n\ttree.Put(3, 2)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)\n\n\ttree.Put(4, 2)\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true)\n\n\ttree.Put(5, 2)\n\tassertValidTree(t, tree, 5)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{5}, true)\n\n\ttree.Put(6, 2)\n\tassertValidTree(t, tree, 6)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true)\n\n\ttree.Put(7, 2)\n\tassertValidTree(t, tree, 7)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true)\n}\n\nfunc TestBTreePut2(t *testing.T) {\n\ttree := New[int, int](4)\n\tassertValidTree(t, tree, 0)\n\n\ttree.Put(0, 0)\n\tassertValidTree(t, tree, 1)\n\tassertValidTreeNode(t, tree.Root, 1, 0, []int{0}, false)\n\n\ttree.Put(2, 2)\n\tassertValidTree(t, tree, 2)\n\tassertValidTreeNode(t, tree.Root, 2, 0, []int{0, 2}, false)\n\n\ttree.Put(1, 1)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false)\n\n\ttree.Put(1, 1)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false)\n\n\ttree.Put(3, 3)\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{2, 3}, true)\n\n\ttree.Put(4, 4)\n\tassertValidTree(t, tree, 5)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{2, 3, 4}, true)\n\n\ttree.Put(5, 5)\n\tassertValidTree(t, tree, 6)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{1, 3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{4, 5}, true)\n}\n\nfunc TestBTreePut3(t *testing.T) {\n\t// http://www.geeksforgeeks.org/b-tree-set-1-insert-2/\n\ttree := New[int, int](6)\n\tassertValidTree(t, tree, 0)\n\n\ttree.Put(10, 0)\n\tassertValidTree(t, tree, 1)\n\tassertValidTreeNode(t, tree.Root, 1, 0, []int{10}, false)\n\n\ttree.Put(20, 1)\n\tassertValidTree(t, tree, 2)\n\tassertValidTreeNode(t, tree.Root, 2, 0, []int{10, 20}, false)\n\n\ttree.Put(30, 2)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 3, 0, []int{10, 20, 30}, false)\n\n\ttree.Put(40, 3)\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 4, 0, []int{10, 20, 30, 40}, false)\n\n\ttree.Put(50, 4)\n\tassertValidTree(t, tree, 5)\n\tassertValidTreeNode(t, tree.Root, 5, 0, []int{10, 20, 30, 40, 50}, false)\n\n\ttree.Put(60, 5)\n\tassertValidTree(t, tree, 6)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{40, 50, 60}, true)\n\n\ttree.Put(70, 6)\n\tassertValidTree(t, tree, 7)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 4, 0, []int{40, 50, 60, 70}, true)\n\n\ttree.Put(80, 7)\n\tassertValidTree(t, tree, 8)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 5, 0, []int{40, 50, 60, 70, 80}, true)\n\n\ttree.Put(90, 8)\n\tassertValidTree(t, tree, 9)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{30, 60}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{40, 50}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 3, 0, []int{70, 80, 90}, true)\n}\n\nfunc TestBTreePut4(t *testing.T) {\n\ttree := New[int, *struct{}](3)\n\tassertValidTree(t, tree, 0)\n\n\ttree.Put(6, nil)\n\tassertValidTree(t, tree, 1)\n\tassertValidTreeNode(t, tree.Root, 1, 0, []int{6}, false)\n\n\ttree.Put(5, nil)\n\tassertValidTree(t, tree, 2)\n\tassertValidTreeNode(t, tree.Root, 2, 0, []int{5, 6}, false)\n\n\ttree.Put(4, nil)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true)\n\n\ttree.Put(3, nil)\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{3, 4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true)\n\n\ttree.Put(2, nil)\n\tassertValidTree(t, tree, 5)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true)\n\n\ttree.Put(1, nil)\n\tassertValidTree(t, tree, 6)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{1, 2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true)\n\n\ttree.Put(0, nil)\n\tassertValidTree(t, tree, 7)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true)\n\n\ttree.Put(-1, nil)\n\tassertValidTree(t, tree, 8)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-1, 0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true)\n\n\ttree.Put(-2, nil)\n\tassertValidTree(t, tree, 9)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 3, []int{-1, 1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{-2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[2], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true)\n\n\ttree.Put(-3, nil)\n\tassertValidTree(t, tree, 10)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 3, []int{-1, 1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-3, -2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[2], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true)\n\n\ttree.Put(-4, nil)\n\tassertValidTree(t, tree, 11)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{-1, 3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{-3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 1, 2, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{-4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{-2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2].Children[0], 1, 0, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2].Children[1], 1, 0, []int{6}, true)\n}\n\nfunc TestBTreeRemove1(t *testing.T) {\n\t// empty\n\ttree := New[int, int](3)\n\ttree.Remove(1)\n\tassertValidTree(t, tree, 0)\n}\n\nfunc TestBTreeRemove2(t *testing.T) {\n\t// leaf node (no underflow)\n\ttree := New[int, *struct{}](3)\n\ttree.Put(1, nil)\n\ttree.Put(2, nil)\n\n\ttree.Remove(1)\n\tassertValidTree(t, tree, 1)\n\tassertValidTreeNode(t, tree.Root, 1, 0, []int{2}, false)\n\n\ttree.Remove(2)\n\tassertValidTree(t, tree, 0)\n}\n\nfunc TestBTreeRemove3(t *testing.T) {\n\t// merge with right (underflow)\n\t{\n\t\ttree := New[int, *struct{}](3)\n\t\ttree.Put(1, nil)\n\t\ttree.Put(2, nil)\n\t\ttree.Put(3, nil)\n\n\t\ttree.Remove(1)\n\t\tassertValidTree(t, tree, 2)\n\t\tassertValidTreeNode(t, tree.Root, 2, 0, []int{2, 3}, false)\n\t}\n\t// merge with left (underflow)\n\t{\n\t\ttree := New[int, *struct{}](3)\n\t\ttree.Put(1, nil)\n\t\ttree.Put(2, nil)\n\t\ttree.Put(3, nil)\n\n\t\ttree.Remove(3)\n\t\tassertValidTree(t, tree, 2)\n\t\tassertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false)\n\t}\n}\n\nfunc TestBTreeRemove4(t *testing.T) {\n\t// rotate left (underflow)\n\ttree := New[int, *struct{}](3)\n\ttree.Put(1, nil)\n\ttree.Put(2, nil)\n\ttree.Put(3, nil)\n\ttree.Put(4, nil)\n\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true)\n\n\ttree.Remove(1)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true)\n}\n\nfunc TestBTreeRemove5(t *testing.T) {\n\t// rotate right (underflow)\n\ttree := New[int, *struct{}](3)\n\ttree.Put(1, nil)\n\ttree.Put(2, nil)\n\ttree.Put(3, nil)\n\ttree.Put(0, nil)\n\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{0, 1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)\n\n\ttree.Remove(3)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true)\n}\n\nfunc TestBTreeRemove6(t *testing.T) {\n\t// root height reduction after a series of underflows on right side\n\t// use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html\n\ttree := New[int, *struct{}](3)\n\ttree.Put(1, nil)\n\ttree.Put(2, nil)\n\ttree.Put(3, nil)\n\ttree.Put(4, nil)\n\ttree.Put(5, nil)\n\ttree.Put(6, nil)\n\ttree.Put(7, nil)\n\n\tassertValidTree(t, tree, 7)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true)\n\n\ttree.Remove(7)\n\tassertValidTree(t, tree, 6)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true)\n}\n\nfunc TestBTreeRemove7(t *testing.T) {\n\t// root height reduction after a series of underflows on left side\n\t// use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html\n\ttree := New[int, *struct{}](3)\n\ttree.Put(1, nil)\n\ttree.Put(2, nil)\n\ttree.Put(3, nil)\n\ttree.Put(4, nil)\n\ttree.Put(5, nil)\n\ttree.Put(6, nil)\n\ttree.Put(7, nil)\n\n\tassertValidTree(t, tree, 7)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true)\n\n\ttree.Remove(1) // series of underflows\n\tassertValidTree(t, tree, 6)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{4, 6}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{2, 3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{7}, true)\n\n\t// clear all remaining\n\ttree.Remove(2)\n\tassertValidTree(t, tree, 5)\n\tassertValidTreeNode(t, tree.Root, 2, 3, []int{4, 6}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{7}, true)\n\n\ttree.Remove(3)\n\tassertValidTree(t, tree, 4)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{4, 5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{7}, true)\n\n\ttree.Remove(4)\n\tassertValidTree(t, tree, 3)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{7}, true)\n\n\ttree.Remove(5)\n\tassertValidTree(t, tree, 2)\n\tassertValidTreeNode(t, tree.Root, 2, 0, []int{6, 7}, false)\n\n\ttree.Remove(6)\n\tassertValidTree(t, tree, 1)\n\tassertValidTreeNode(t, tree.Root, 1, 0, []int{7}, false)\n\n\ttree.Remove(7)\n\tassertValidTree(t, tree, 0)\n}\n\nfunc TestBTreeRemove8(t *testing.T) {\n\t// use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html\n\ttree := New[int, *struct{}](3)\n\ttree.Put(1, nil)\n\ttree.Put(2, nil)\n\ttree.Put(3, nil)\n\ttree.Put(4, nil)\n\ttree.Put(5, nil)\n\ttree.Put(6, nil)\n\ttree.Put(7, nil)\n\ttree.Put(8, nil)\n\ttree.Put(9, nil)\n\n\tassertValidTree(t, tree, 9)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 2, 3, []int{6, 8}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[2], 1, 0, []int{9}, true)\n\n\ttree.Remove(1)\n\tassertValidTree(t, tree, 8)\n\tassertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false)\n\tassertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{4}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{8}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{2, 3}, true)\n\tassertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{5}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{7}, true)\n\tassertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{9}, true)\n}\n\nfunc TestBTreeRemove9(t *testing.T) {\n\tconst max = 1000\n\torders := []int{3, 4, 5, 6, 7, 8, 9, 10, 20, 100, 500, 1000, 5000, 10000}\n\tfor _, order := range orders {\n\n\t\ttree := New[int, int](order)\n\n\t\t{\n\t\t\tfor i := 1; i <= max; i++ {\n\t\t\t\ttree.Put(i, i)\n\t\t\t}\n\t\t\tassertValidTree(t, tree, max)\n\n\t\t\tfor i := 1; i <= max; i++ {\n\t\t\t\tif _, found := tree.Get(i); !found {\n\t\t\t\t\tt.Errorf(\"Not found %v\", i)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor i := 1; i <= max; i++ {\n\t\t\t\ttree.Remove(i)\n\t\t\t}\n\t\t\tassertValidTree(t, tree, 0)\n\t\t}\n\n\t\t{\n\t\t\tfor i := max; i > 0; i-- {\n\t\t\t\ttree.Put(i, i)\n\t\t\t}\n\t\t\tassertValidTree(t, tree, max)\n\n\t\t\tfor i := max; i > 0; i-- {\n\t\t\t\tif _, found := tree.Get(i); !found {\n\t\t\t\t\tt.Errorf(\"Not found %v\", i)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor i := max; i > 0; i-- {\n\t\t\t\ttree.Remove(i)\n\t\t\t}\n\t\t\tassertValidTree(t, tree, 0)\n\t\t}\n\t}\n}\n\nfunc TestBTreeHeight(t *testing.T) {\n\ttree := New[int, int](3)\n\tif actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(1, 0)\n\tif actualValue, expectedValue := tree.Height(), 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(2, 1)\n\tif actualValue, expectedValue := tree.Height(), 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(3, 2)\n\tif actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(4, 2)\n\tif actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(5, 2)\n\tif actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(6, 2)\n\tif actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Put(7, 2)\n\tif actualValue, expectedValue := tree.Height(), 3; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttree.Remove(1)\n\ttree.Remove(2)\n\ttree.Remove(3)\n\ttree.Remove(4)\n\ttree.Remove(5)\n\ttree.Remove(6)\n\ttree.Remove(7)\n\tif actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeLeftAndRight(t *testing.T) {\n\ttree := New[int, string](3)\n\n\tif actualValue := tree.Left(); actualValue != nil {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := tree.Right(); actualValue != nil {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\n\ttree.Put(1, \"a\")\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\") // overwrite\n\ttree.Put(2, \"b\")\n\n\tif actualValue, expectedValue := tree.LeftKey(), 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.LeftValue(), \"x\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tif actualValue, expectedValue := tree.RightKey(), 7; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.RightValue(), \"g\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIteratorValuesAndKeys(t *testing.T) {\n\ttree := New[int, string](4)\n\ttree.Put(4, \"d\")\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(7, \"g\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"x\") // override\n\tif actualValue, expectedValue := tree.Keys(), []int{1, 2, 3, 4, 5, 6, 7}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{\"x\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := tree.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n}\n\nfunc TestBTreeIteratorNextOnEmpty(t *testing.T) {\n\ttree := New[int, string](3)\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t}\n}\n\nfunc TestBTreeIteratorPrevOnEmpty(t *testing.T) {\n\ttree := New[int, string](3)\n\tit := tree.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t}\n}\n\nfunc TestBTreeIterator1Next(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator1Prev(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator2Next(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator2Prev(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator3Next(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(1, \"a\")\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator3Prev(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(1, \"a\")\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator4Next(t *testing.T) {\n\ttree := New[int, int](3)\n\ttree.Put(13, 5)\n\ttree.Put(8, 3)\n\ttree.Put(17, 7)\n\ttree.Put(1, 1)\n\ttree.Put(11, 4)\n\ttree.Put(15, 6)\n\ttree.Put(25, 9)\n\ttree.Put(6, 2)\n\ttree.Put(22, 8)\n\ttree.Put(27, 10)\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tvalue := it.Value()\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIterator4Prev(t *testing.T) {\n\ttree := New[int, int](3)\n\ttree.Put(13, 5)\n\ttree.Put(8, 3)\n\ttree.Put(17, 7)\n\ttree.Put(1, 1)\n\ttree.Put(11, 4)\n\ttree.Put(15, 6)\n\ttree.Put(25, 9)\n\ttree.Put(6, 2)\n\ttree.Put(22, 8)\n\ttree.Put(27, 10)\n\tit := tree.Iterator()\n\tcount := tree.Size()\n\tfor it.Next() {\n\t}\n\tfor it.Prev() {\n\t\tvalue := it.Value()\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcount--\n\t}\n\tif actualValue, expectedValue := count, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeIteratorBegin(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.Begin()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tfor it.Next() {\n\t}\n\n\tit.Begin()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.Next()\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestBTreeIteratorEnd(t *testing.T) {\n\ttree := New[int, string](3)\n\tit := tree.Iterator()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.End()\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit.End()\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.Prev()\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestBTreeIteratorFirst(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestBTreeIteratorLast(t *testing.T) {\n\ttree := New[int, string](3)\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestBTreeSearch(t *testing.T) {\n\t{\n\t\ttree := New[int, int](3)\n\t\ttree.Root = &Node[int, int]{Entries: []*Entry[int, int]{}, Children: make([]*Node[int, int], 0)}\n\t\ttests := [][]interface{}{\n\t\t\t{0, 0, false},\n\t\t}\n\t\tfor _, test := range tests {\n\t\t\tindex, found := tree.search(tree.Root, test[0].(int))\n\t\t\tif actualValue, expectedValue := index, test[1]; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\t\tif actualValue, expectedValue := found, test[2]; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\ttree := New[int, int](3)\n\t\ttree.Root = &Node[int, int]{Entries: []*Entry[int, int]{{2, 0}, {4, 1}, {6, 2}}, Children: []*Node[int, int]{}}\n\t\ttests := [][]interface{}{\n\t\t\t{0, 0, false},\n\t\t\t{1, 0, false},\n\t\t\t{2, 0, true},\n\t\t\t{3, 1, false},\n\t\t\t{4, 1, true},\n\t\t\t{5, 2, false},\n\t\t\t{6, 2, true},\n\t\t\t{7, 3, false},\n\t\t}\n\t\tfor _, test := range tests {\n\t\t\tindex, found := tree.search(tree.Root, test[0].(int))\n\t\t\tif actualValue, expectedValue := index, test[1]; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\t\tif actualValue, expectedValue := found, test[2]; actualValue != expectedValue {\n\t\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc assertValidTree[K comparable, V any](t *testing.T, tree *Tree[K, V], expectedSize int) {\n\tif actualValue, expectedValue := tree.size, expectedSize; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v for tree size\", actualValue, expectedValue)\n\t}\n}\n\nfunc assertValidTreeNode[K comparable, V any](t *testing.T, node *Node[K, V], expectedEntries int, expectedChildren int, keys []K, hasParent bool) {\n\tif actualValue, expectedValue := node.Parent != nil, hasParent; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v for hasParent\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := len(node.Entries), expectedEntries; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v for entries size\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := len(node.Children), expectedChildren; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v for children size\", actualValue, expectedValue)\n\t}\n\tfor i, key := range keys {\n\t\tif actualValue, expectedValue := node.Entries[i].Key, key; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v for key\", actualValue, expectedValue)\n\t\t}\n\t}\n}\n\nfunc TestBTreeIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\ttree := New[int, string](3)\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\ttree := New[int, string](3)\n\t\ttree.Put(0, \"xx\")\n\t\ttree.Put(1, \"yy\")\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\ttree := New[int, string](3)\n\t\ttree.Put(2, \"cc\")\n\t\ttree.Put(0, \"aa\")\n\t\ttree.Put(1, \"bb\")\n\t\tit := tree.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestBTreeIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\ttree := New[int, string](3)\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\ttree := New[int, string](3)\n\t\ttree.Put(0, \"xx\")\n\t\ttree.Put(1, \"yy\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\ttree := New[int, string](3)\n\t\ttree.Put(2, \"cc\")\n\t\ttree.Put(0, \"aa\")\n\t\ttree.Put(1, \"bb\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestBTreeSerialization(t *testing.T) {\n\ttree := New[string, string](3)\n\ttree.Put(\"c\", \"3\")\n\ttree.Put(\"b\", \"2\")\n\ttree.Put(\"a\", \"1\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := tree.Keys(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := tree.Values(), []string{\"1\", \"2\", \"3\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := tree.ToJSON()\n\tassert()\n\n\terr = tree.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", tree})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\tintTree := New[string, int](3)\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), intTree)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tif actualValue, expectedValue := intTree.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := intTree.Keys(), []string{\"a\", \"b\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := intTree.Values(), []int{1, 2}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestBTreeString(t *testing.T) {\n\tc := New[string, int](3)\n\tc.Put(\"a\", 1)\n\tif !strings.HasPrefix(c.String(), \"BTree\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Put(n, struct{}{})\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkBTreeGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkBTreeGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkBTreeGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkBTreeGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkBTreePut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}](128)\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkBTreePut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkBTreePut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkBTreePut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkBTreeRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkBTreeRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkBTreeRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkBTreeRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}](128)\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n"
  },
  {
    "path": "trees/btree/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage btree\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithKey[string, int] = (*Iterator[string, int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[K comparable, V any] struct {\n\ttree     *Tree[K, V]\n\tnode     *Node[K, V]\n\tentry    *Entry[K, V]\n\tposition position\n}\n\ntype position byte\n\nconst (\n\tbegin, between, end position = 0, 1, 2\n)\n\n// Iterator returns a stateful iterator whose elements are key/value pairs.\nfunc (tree *Tree[K, V]) Iterator() *Iterator[K, V] {\n\treturn &Iterator[K, V]{tree: tree, node: nil, position: begin}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Next() bool {\n\t// If already at end, go to end\n\tif iterator.position == end {\n\t\tgoto end\n\t}\n\t// If at beginning, get the left-most entry in the tree\n\tif iterator.position == begin {\n\t\tleft := iterator.tree.Left()\n\t\tif left == nil {\n\t\t\tgoto end\n\t\t}\n\t\titerator.node = left\n\t\titerator.entry = left.Entries[0]\n\t\tgoto between\n\t}\n\t{\n\t\t// Find current entry position in current node\n\t\te, _ := iterator.tree.search(iterator.node, iterator.entry.Key)\n\t\t// Try to go down to the child right of the current entry\n\t\tif e+1 < len(iterator.node.Children) {\n\t\t\titerator.node = iterator.node.Children[e+1]\n\t\t\t// Try to go down to the child left of the current node\n\t\t\tfor len(iterator.node.Children) > 0 {\n\t\t\t\titerator.node = iterator.node.Children[0]\n\t\t\t}\n\t\t\t// Return the left-most entry\n\t\t\titerator.entry = iterator.node.Entries[0]\n\t\t\tgoto between\n\t\t}\n\t\t// Above assures that we have reached a leaf node, so return the next entry in current node (if any)\n\t\tif e+1 < len(iterator.node.Entries) {\n\t\t\titerator.entry = iterator.node.Entries[e+1]\n\t\t\tgoto between\n\t\t}\n\t}\n\t// Reached leaf node and there are no entries to the right of the current entry, so go up to the parent\n\tfor iterator.node.Parent != nil {\n\t\titerator.node = iterator.node.Parent\n\t\t// Find next entry position in current node (note: search returns the first equal or bigger than entry)\n\t\te, _ := iterator.tree.search(iterator.node, iterator.entry.Key)\n\t\t// Check that there is a next entry position in current node\n\t\tif e < len(iterator.node.Entries) {\n\t\t\titerator.entry = iterator.node.Entries[e]\n\t\t\tgoto between\n\t\t}\n\t}\n\nend:\n\titerator.End()\n\treturn false\n\nbetween:\n\titerator.position = between\n\treturn true\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Prev() bool {\n\t// If already at beginning, go to begin\n\tif iterator.position == begin {\n\t\tgoto begin\n\t}\n\t// If at end, get the right-most entry in the tree\n\tif iterator.position == end {\n\t\tright := iterator.tree.Right()\n\t\tif right == nil {\n\t\t\tgoto begin\n\t\t}\n\t\titerator.node = right\n\t\titerator.entry = right.Entries[len(right.Entries)-1]\n\t\tgoto between\n\t}\n\t{\n\t\t// Find current entry position in current node\n\t\te, _ := iterator.tree.search(iterator.node, iterator.entry.Key)\n\t\t// Try to go down to the child left of the current entry\n\t\tif e < len(iterator.node.Children) {\n\t\t\titerator.node = iterator.node.Children[e]\n\t\t\t// Try to go down to the child right of the current node\n\t\t\tfor len(iterator.node.Children) > 0 {\n\t\t\t\titerator.node = iterator.node.Children[len(iterator.node.Children)-1]\n\t\t\t}\n\t\t\t// Return the right-most entry\n\t\t\titerator.entry = iterator.node.Entries[len(iterator.node.Entries)-1]\n\t\t\tgoto between\n\t\t}\n\t\t// Above assures that we have reached a leaf node, so return the previous entry in current node (if any)\n\t\tif e-1 >= 0 {\n\t\t\titerator.entry = iterator.node.Entries[e-1]\n\t\t\tgoto between\n\t\t}\n\t}\n\t// Reached leaf node and there are no entries to the left of the current entry, so go up to the parent\n\tfor iterator.node.Parent != nil {\n\t\titerator.node = iterator.node.Parent\n\t\t// Find previous entry position in current node (note: search returns the first equal or bigger than entry)\n\t\te, _ := iterator.tree.search(iterator.node, iterator.entry.Key)\n\t\t// Check that there is a previous entry position in current node\n\t\tif e-1 >= 0 {\n\t\t\titerator.entry = iterator.node.Entries[e-1]\n\t\t\tgoto between\n\t\t}\n\t}\n\nbegin:\n\titerator.Begin()\n\treturn false\n\nbetween:\n\titerator.position = between\n\treturn true\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Value() V {\n\treturn iterator.entry.Value\n}\n\n// Key returns the current element's key.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Key() K {\n\treturn iterator.entry.Key\n}\n\n// Node returns the current element's node.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Node() *Node[K, V] {\n\treturn iterator.node\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[K, V]) Begin() {\n\titerator.node = nil\n\titerator.position = begin\n\titerator.entry = nil\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[K, V]) End() {\n\titerator.node = nil\n\titerator.position = end\n\titerator.entry = nil\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator\nfunc (iterator *Iterator[K, V]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) NextTo(f func(key K, value V) bool) bool {\n\tfor iterator.Next() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) PrevTo(f func(key K, value V) bool) bool {\n\tfor iterator.Prev() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "trees/btree/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage btree\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Tree[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Tree[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the tree.\nfunc (tree *Tree[K, V]) ToJSON() ([]byte, error) {\n\telements := make(map[K]V)\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t\telements[it.Key()] = it.Value()\n\t}\n\treturn json.Marshal(&elements)\n}\n\n// FromJSON populates the tree from the input JSON representation.\nfunc (tree *Tree[K, V]) FromJSON(data []byte) error {\n\telements := make(map[K]V)\n\terr := json.Unmarshal(data, &elements)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttree.Clear()\n\tfor key, value := range elements {\n\t\ttree.Put(key, value)\n\t}\n\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (tree *Tree[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn tree.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (tree *Tree[K, V]) MarshalJSON() ([]byte, error) {\n\treturn tree.ToJSON()\n}\n"
  },
  {
    "path": "trees/redblacktree/iterator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage redblacktree\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Assert Iterator implementation\nvar _ containers.ReverseIteratorWithKey[string, int] = (*Iterator[string, int])(nil)\n\n// Iterator holding the iterator's state\ntype Iterator[K comparable, V any] struct {\n\ttree     *Tree[K, V]\n\tnode     *Node[K, V]\n\tposition position\n}\n\ntype position byte\n\nconst (\n\tbegin, between, end position = 0, 1, 2\n)\n\n// Iterator returns a stateful iterator whose elements are key/value pairs.\nfunc (tree *Tree[K, V]) Iterator() *Iterator[K, V] {\n\treturn &Iterator[K, V]{tree: tree, node: nil, position: begin}\n}\n\n// IteratorAt returns a stateful iterator whose elements are key/value pairs that is initialised at a particular node.\nfunc (tree *Tree[K, V]) IteratorAt(node *Node[K, V]) *Iterator[K, V] {\n\treturn &Iterator[K, V]{tree: tree, node: node, position: between}\n}\n\n// Next moves the iterator to the next element and returns true if there was a next element in the container.\n// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().\n// If Next() was called for the first time, then it will point the iterator to the first element if it exists.\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Next() bool {\n\tif iterator.position == end {\n\t\tgoto end\n\t}\n\tif iterator.position == begin {\n\t\tleft := iterator.tree.Left()\n\t\tif left == nil {\n\t\t\tgoto end\n\t\t}\n\t\titerator.node = left\n\t\tgoto between\n\t}\n\tif iterator.node.Right != nil {\n\t\titerator.node = iterator.node.Right\n\t\tfor iterator.node.Left != nil {\n\t\t\titerator.node = iterator.node.Left\n\t\t}\n\t\tgoto between\n\t}\n\tfor iterator.node.Parent != nil {\n\t\tnode := iterator.node\n\t\titerator.node = iterator.node.Parent\n\t\tif node == iterator.node.Left {\n\t\t\tgoto between\n\t\t}\n\t}\n\nend:\n\titerator.node = nil\n\titerator.position = end\n\treturn false\n\nbetween:\n\titerator.position = between\n\treturn true\n}\n\n// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.\n// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Prev() bool {\n\tif iterator.position == begin {\n\t\tgoto begin\n\t}\n\tif iterator.position == end {\n\t\tright := iterator.tree.Right()\n\t\tif right == nil {\n\t\t\tgoto begin\n\t\t}\n\t\titerator.node = right\n\t\tgoto between\n\t}\n\tif iterator.node.Left != nil {\n\t\titerator.node = iterator.node.Left\n\t\tfor iterator.node.Right != nil {\n\t\t\titerator.node = iterator.node.Right\n\t\t}\n\t\tgoto between\n\t}\n\tfor iterator.node.Parent != nil {\n\t\tnode := iterator.node\n\t\titerator.node = iterator.node.Parent\n\t\tif node == iterator.node.Right {\n\t\t\tgoto between\n\t\t}\n\t}\n\nbegin:\n\titerator.node = nil\n\titerator.position = begin\n\treturn false\n\nbetween:\n\titerator.position = between\n\treturn true\n}\n\n// Value returns the current element's value.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Value() V {\n\treturn iterator.node.Value\n}\n\n// Key returns the current element's key.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Key() K {\n\treturn iterator.node.Key\n}\n\n// Node returns the current element's node.\n// Does not modify the state of the iterator.\nfunc (iterator *Iterator[K, V]) Node() *Node[K, V] {\n\treturn iterator.node\n}\n\n// Begin resets the iterator to its initial state (one-before-first)\n// Call Next() to fetch the first element if any.\nfunc (iterator *Iterator[K, V]) Begin() {\n\titerator.node = nil\n\titerator.position = begin\n}\n\n// End moves the iterator past the last element (one-past-the-end).\n// Call Prev() to fetch the last element if any.\nfunc (iterator *Iterator[K, V]) End() {\n\titerator.node = nil\n\titerator.position = end\n}\n\n// First moves the iterator to the first element and returns true if there was a first element in the container.\n// If First() returns true, then first element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator\nfunc (iterator *Iterator[K, V]) First() bool {\n\titerator.Begin()\n\treturn iterator.Next()\n}\n\n// Last moves the iterator to the last element and returns true if there was a last element in the container.\n// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) Last() bool {\n\titerator.End()\n\treturn iterator.Prev()\n}\n\n// NextTo moves the iterator to the next element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If NextTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) NextTo(f func(key K, value V) bool) bool {\n\tfor iterator.Next() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// PrevTo moves the iterator to the previous element from current position that satisfies the condition given by the\n// passed function, and returns true if there was a next element in the container.\n// If PrevTo() returns true, then next element's key and value can be retrieved by Key() and Value().\n// Modifies the state of the iterator.\nfunc (iterator *Iterator[K, V]) PrevTo(f func(key K, value V) bool) bool {\n\tfor iterator.Prev() {\n\t\tkey, value := iterator.Key(), iterator.Value()\n\t\tif f(key, value) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "trees/redblacktree/redblacktree.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package redblacktree implements a red-black tree.\n//\n// Used by TreeSet and TreeMap.\n//\n// Structure is not thread safe.\n//\n// References: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree\npackage redblacktree\n\nimport (\n\t\"cmp\"\n\t\"fmt\"\n\n\t\"github.com/emirpasic/gods/v2/trees\"\n\t\"github.com/emirpasic/gods/v2/utils\"\n)\n\n// Assert Tree implementation\nvar _ trees.Tree[int] = (*Tree[string, int])(nil)\n\ntype color bool\n\nconst (\n\tblack, red color = true, false\n)\n\n// Tree holds elements of the red-black tree\ntype Tree[K comparable, V any] struct {\n\tRoot       *Node[K, V]\n\tsize       int\n\tComparator utils.Comparator[K]\n}\n\n// Node is a single element within the tree\ntype Node[K comparable, V any] struct {\n\tKey    K\n\tValue  V\n\tcolor  color\n\tLeft   *Node[K, V]\n\tRight  *Node[K, V]\n\tParent *Node[K, V]\n}\n\n// New instantiates a red-black tree with the built-in comparator for K\nfunc New[K cmp.Ordered, V any]() *Tree[K, V] {\n\treturn &Tree[K, V]{Comparator: cmp.Compare[K]}\n}\n\n// NewWith instantiates a red-black tree with the custom comparator.\nfunc NewWith[K comparable, V any](comparator utils.Comparator[K]) *Tree[K, V] {\n\treturn &Tree[K, V]{Comparator: comparator}\n}\n\n// Put inserts node into the tree.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Put(key K, value V) {\n\tvar insertedNode *Node[K, V]\n\tif tree.Root == nil {\n\t\t// Assert key is of comparator's type for initial tree\n\t\ttree.Comparator(key, key)\n\t\ttree.Root = &Node[K, V]{Key: key, Value: value, color: red}\n\t\tinsertedNode = tree.Root\n\t} else {\n\t\tnode := tree.Root\n\t\tloop := true\n\t\tfor loop {\n\t\t\tcompare := tree.Comparator(key, node.Key)\n\t\t\tswitch {\n\t\t\tcase compare == 0:\n\t\t\t\tnode.Key = key\n\t\t\t\tnode.Value = value\n\t\t\t\treturn\n\t\t\tcase compare < 0:\n\t\t\t\tif node.Left == nil {\n\t\t\t\t\tnode.Left = &Node[K, V]{Key: key, Value: value, color: red}\n\t\t\t\t\tinsertedNode = node.Left\n\t\t\t\t\tloop = false\n\t\t\t\t} else {\n\t\t\t\t\tnode = node.Left\n\t\t\t\t}\n\t\t\tcase compare > 0:\n\t\t\t\tif node.Right == nil {\n\t\t\t\t\tnode.Right = &Node[K, V]{Key: key, Value: value, color: red}\n\t\t\t\t\tinsertedNode = node.Right\n\t\t\t\t\tloop = false\n\t\t\t\t} else {\n\t\t\t\t\tnode = node.Right\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinsertedNode.Parent = node\n\t}\n\ttree.insertCase1(insertedNode)\n\ttree.size++\n}\n\n// Get searches the node in the tree by key and returns its value or nil if key is not found in tree.\n// Second return parameter is true if key was found, otherwise false.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Get(key K) (value V, found bool) {\n\tnode := tree.lookup(key)\n\tif node != nil {\n\t\treturn node.Value, true\n\t}\n\treturn value, false\n}\n\n// GetNode searches the node in the tree by key and returns its node or nil if key is not found in tree.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) GetNode(key K) *Node[K, V] {\n\treturn tree.lookup(key)\n}\n\n// Remove remove the node from the tree by key.\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Remove(key K) {\n\tvar child *Node[K, V]\n\tnode := tree.lookup(key)\n\tif node == nil {\n\t\treturn\n\t}\n\tif node.Left != nil && node.Right != nil {\n\t\tpred := node.Left.maximumNode()\n\t\tnode.Key = pred.Key\n\t\tnode.Value = pred.Value\n\t\tnode = pred\n\t}\n\tif node.Left == nil || node.Right == nil {\n\t\tif node.Right == nil {\n\t\t\tchild = node.Left\n\t\t} else {\n\t\t\tchild = node.Right\n\t\t}\n\t\tif node.color == black {\n\t\t\tnode.color = nodeColor(child)\n\t\t\ttree.deleteCase1(node)\n\t\t}\n\t\ttree.replaceNode(node, child)\n\t\tif node.Parent == nil && child != nil {\n\t\t\tchild.color = black\n\t\t}\n\t}\n\ttree.size--\n}\n\n// Empty returns true if tree does not contain any nodes\nfunc (tree *Tree[K, V]) Empty() bool {\n\treturn tree.size == 0\n}\n\n// Size returns number of nodes in the tree.\nfunc (tree *Tree[K, V]) Size() int {\n\treturn tree.size\n}\n\n// Size returns the number of elements stored in the subtree.\n// Computed dynamically on each call, i.e. the subtree is traversed to count the number of the nodes.\nfunc (node *Node[K, V]) Size() int {\n\tif node == nil {\n\t\treturn 0\n\t}\n\tsize := 1\n\tif node.Left != nil {\n\t\tsize += node.Left.Size()\n\t}\n\tif node.Right != nil {\n\t\tsize += node.Right.Size()\n\t}\n\treturn size\n}\n\n// Keys returns all keys in-order\nfunc (tree *Tree[K, V]) Keys() []K {\n\tkeys := make([]K, tree.size)\n\tit := tree.Iterator()\n\tfor i := 0; it.Next(); i++ {\n\t\tkeys[i] = it.Key()\n\t}\n\treturn keys\n}\n\n// Values returns all values in-order based on the key.\nfunc (tree *Tree[K, V]) Values() []V {\n\tvalues := make([]V, tree.size)\n\tit := tree.Iterator()\n\tfor i := 0; it.Next(); i++ {\n\t\tvalues[i] = it.Value()\n\t}\n\treturn values\n}\n\n// Left returns the left-most (min) node or nil if tree is empty.\nfunc (tree *Tree[K, V]) Left() *Node[K, V] {\n\tvar parent *Node[K, V]\n\tcurrent := tree.Root\n\tfor current != nil {\n\t\tparent = current\n\t\tcurrent = current.Left\n\t}\n\treturn parent\n}\n\n// Right returns the right-most (max) node or nil if tree is empty.\nfunc (tree *Tree[K, V]) Right() *Node[K, V] {\n\tvar parent *Node[K, V]\n\tcurrent := tree.Root\n\tfor current != nil {\n\t\tparent = current\n\t\tcurrent = current.Right\n\t}\n\treturn parent\n}\n\n// Floor Finds floor node of the input key, return the floor node or nil if no floor is found.\n// Second return parameter is true if floor was found, otherwise false.\n//\n// Floor node is defined as the largest node that is smaller than or equal to the given node.\n// A floor node may not be found, either because the tree is empty, or because\n// all nodes in the tree are larger than the given node.\n//\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Floor(key K) (floor *Node[K, V], found bool) {\n\tfound = false\n\tnode := tree.Root\n\tfor node != nil {\n\t\tcompare := tree.Comparator(key, node.Key)\n\t\tswitch {\n\t\tcase compare == 0:\n\t\t\treturn node, true\n\t\tcase compare < 0:\n\t\t\tnode = node.Left\n\t\tcase compare > 0:\n\t\t\tfloor, found = node, true\n\t\t\tnode = node.Right\n\t\t}\n\t}\n\tif found {\n\t\treturn floor, true\n\t}\n\treturn nil, false\n}\n\n// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found.\n// Second return parameter is true if ceiling was found, otherwise false.\n//\n// Ceiling node is defined as the smallest node that is larger than or equal to the given node.\n// A ceiling node may not be found, either because the tree is empty, or because\n// all nodes in the tree are smaller than the given node.\n//\n// Key should adhere to the comparator's type assertion, otherwise method panics.\nfunc (tree *Tree[K, V]) Ceiling(key K) (ceiling *Node[K, V], found bool) {\n\tfound = false\n\tnode := tree.Root\n\tfor node != nil {\n\t\tcompare := tree.Comparator(key, node.Key)\n\t\tswitch {\n\t\tcase compare == 0:\n\t\t\treturn node, true\n\t\tcase compare < 0:\n\t\t\tceiling, found = node, true\n\t\t\tnode = node.Left\n\t\tcase compare > 0:\n\t\t\tnode = node.Right\n\t\t}\n\t}\n\tif found {\n\t\treturn ceiling, true\n\t}\n\treturn nil, false\n}\n\n// Clear removes all nodes from the tree.\nfunc (tree *Tree[K, V]) Clear() {\n\ttree.Root = nil\n\ttree.size = 0\n}\n\n// String returns a string representation of container\nfunc (tree *Tree[K, V]) String() string {\n\tstr := \"RedBlackTree\\n\"\n\tif !tree.Empty() {\n\t\toutput(tree.Root, \"\", true, &str)\n\t}\n\treturn str\n}\n\nfunc (node *Node[K, V]) String() string {\n\treturn fmt.Sprintf(\"%v\", node.Key)\n}\n\nfunc output[K comparable, V any](node *Node[K, V], prefix string, isTail bool, str *string) {\n\tif node.Right != nil {\n\t\tnewPrefix := prefix\n\t\tif isTail {\n\t\t\tnewPrefix += \"│   \"\n\t\t} else {\n\t\t\tnewPrefix += \"    \"\n\t\t}\n\t\toutput(node.Right, newPrefix, false, str)\n\t}\n\t*str += prefix\n\tif isTail {\n\t\t*str += \"└── \"\n\t} else {\n\t\t*str += \"┌── \"\n\t}\n\t*str += node.String() + \"\\n\"\n\tif node.Left != nil {\n\t\tnewPrefix := prefix\n\t\tif isTail {\n\t\t\tnewPrefix += \"    \"\n\t\t} else {\n\t\t\tnewPrefix += \"│   \"\n\t\t}\n\t\toutput(node.Left, newPrefix, true, str)\n\t}\n}\n\nfunc (tree *Tree[K, V]) lookup(key K) *Node[K, V] {\n\tnode := tree.Root\n\tfor node != nil {\n\t\tcompare := tree.Comparator(key, node.Key)\n\t\tswitch {\n\t\tcase compare == 0:\n\t\t\treturn node\n\t\tcase compare < 0:\n\t\t\tnode = node.Left\n\t\tcase compare > 0:\n\t\t\tnode = node.Right\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (node *Node[K, V]) grandparent() *Node[K, V] {\n\tif node != nil && node.Parent != nil {\n\t\treturn node.Parent.Parent\n\t}\n\treturn nil\n}\n\nfunc (node *Node[K, V]) uncle() *Node[K, V] {\n\tif node == nil || node.Parent == nil || node.Parent.Parent == nil {\n\t\treturn nil\n\t}\n\treturn node.Parent.sibling()\n}\n\nfunc (node *Node[K, V]) sibling() *Node[K, V] {\n\tif node == nil || node.Parent == nil {\n\t\treturn nil\n\t}\n\tif node == node.Parent.Left {\n\t\treturn node.Parent.Right\n\t}\n\treturn node.Parent.Left\n}\n\nfunc (tree *Tree[K, V]) rotateLeft(node *Node[K, V]) {\n\tright := node.Right\n\ttree.replaceNode(node, right)\n\tnode.Right = right.Left\n\tif right.Left != nil {\n\t\tright.Left.Parent = node\n\t}\n\tright.Left = node\n\tnode.Parent = right\n}\n\nfunc (tree *Tree[K, V]) rotateRight(node *Node[K, V]) {\n\tleft := node.Left\n\ttree.replaceNode(node, left)\n\tnode.Left = left.Right\n\tif left.Right != nil {\n\t\tleft.Right.Parent = node\n\t}\n\tleft.Right = node\n\tnode.Parent = left\n}\n\nfunc (tree *Tree[K, V]) replaceNode(old *Node[K, V], new *Node[K, V]) {\n\tif old.Parent == nil {\n\t\ttree.Root = new\n\t} else {\n\t\tif old == old.Parent.Left {\n\t\t\told.Parent.Left = new\n\t\t} else {\n\t\t\told.Parent.Right = new\n\t\t}\n\t}\n\tif new != nil {\n\t\tnew.Parent = old.Parent\n\t}\n}\n\nfunc (tree *Tree[K, V]) insertCase1(node *Node[K, V]) {\n\tif node.Parent == nil {\n\t\tnode.color = black\n\t} else {\n\t\ttree.insertCase2(node)\n\t}\n}\n\nfunc (tree *Tree[K, V]) insertCase2(node *Node[K, V]) {\n\tif nodeColor(node.Parent) == black {\n\t\treturn\n\t}\n\ttree.insertCase3(node)\n}\n\nfunc (tree *Tree[K, V]) insertCase3(node *Node[K, V]) {\n\tuncle := node.uncle()\n\tif nodeColor(uncle) == red {\n\t\tnode.Parent.color = black\n\t\tuncle.color = black\n\t\tnode.grandparent().color = red\n\t\ttree.insertCase1(node.grandparent())\n\t} else {\n\t\ttree.insertCase4(node)\n\t}\n}\n\nfunc (tree *Tree[K, V]) insertCase4(node *Node[K, V]) {\n\tgrandparent := node.grandparent()\n\tif node == node.Parent.Right && node.Parent == grandparent.Left {\n\t\ttree.rotateLeft(node.Parent)\n\t\tnode = node.Left\n\t} else if node == node.Parent.Left && node.Parent == grandparent.Right {\n\t\ttree.rotateRight(node.Parent)\n\t\tnode = node.Right\n\t}\n\ttree.insertCase5(node)\n}\n\nfunc (tree *Tree[K, V]) insertCase5(node *Node[K, V]) {\n\tnode.Parent.color = black\n\tgrandparent := node.grandparent()\n\tgrandparent.color = red\n\tif node == node.Parent.Left && node.Parent == grandparent.Left {\n\t\ttree.rotateRight(grandparent)\n\t} else if node == node.Parent.Right && node.Parent == grandparent.Right {\n\t\ttree.rotateLeft(grandparent)\n\t}\n}\n\nfunc (node *Node[K, V]) maximumNode() *Node[K, V] {\n\tif node == nil {\n\t\treturn nil\n\t}\n\tfor node.Right != nil {\n\t\tnode = node.Right\n\t}\n\treturn node\n}\n\nfunc (tree *Tree[K, V]) deleteCase1(node *Node[K, V]) {\n\tif node.Parent == nil {\n\t\treturn\n\t}\n\ttree.deleteCase2(node)\n}\n\nfunc (tree *Tree[K, V]) deleteCase2(node *Node[K, V]) {\n\tsibling := node.sibling()\n\tif nodeColor(sibling) == red {\n\t\tnode.Parent.color = red\n\t\tsibling.color = black\n\t\tif node == node.Parent.Left {\n\t\t\ttree.rotateLeft(node.Parent)\n\t\t} else {\n\t\t\ttree.rotateRight(node.Parent)\n\t\t}\n\t}\n\ttree.deleteCase3(node)\n}\n\nfunc (tree *Tree[K, V]) deleteCase3(node *Node[K, V]) {\n\tsibling := node.sibling()\n\tif nodeColor(node.Parent) == black &&\n\t\tnodeColor(sibling) == black &&\n\t\tnodeColor(sibling.Left) == black &&\n\t\tnodeColor(sibling.Right) == black {\n\t\tsibling.color = red\n\t\ttree.deleteCase1(node.Parent)\n\t} else {\n\t\ttree.deleteCase4(node)\n\t}\n}\n\nfunc (tree *Tree[K, V]) deleteCase4(node *Node[K, V]) {\n\tsibling := node.sibling()\n\tif nodeColor(node.Parent) == red &&\n\t\tnodeColor(sibling) == black &&\n\t\tnodeColor(sibling.Left) == black &&\n\t\tnodeColor(sibling.Right) == black {\n\t\tsibling.color = red\n\t\tnode.Parent.color = black\n\t} else {\n\t\ttree.deleteCase5(node)\n\t}\n}\n\nfunc (tree *Tree[K, V]) deleteCase5(node *Node[K, V]) {\n\tsibling := node.sibling()\n\tif node == node.Parent.Left &&\n\t\tnodeColor(sibling) == black &&\n\t\tnodeColor(sibling.Left) == red &&\n\t\tnodeColor(sibling.Right) == black {\n\t\tsibling.color = red\n\t\tsibling.Left.color = black\n\t\ttree.rotateRight(sibling)\n\t} else if node == node.Parent.Right &&\n\t\tnodeColor(sibling) == black &&\n\t\tnodeColor(sibling.Right) == red &&\n\t\tnodeColor(sibling.Left) == black {\n\t\tsibling.color = red\n\t\tsibling.Right.color = black\n\t\ttree.rotateLeft(sibling)\n\t}\n\ttree.deleteCase6(node)\n}\n\nfunc (tree *Tree[K, V]) deleteCase6(node *Node[K, V]) {\n\tsibling := node.sibling()\n\tsibling.color = nodeColor(node.Parent)\n\tnode.Parent.color = black\n\tif node == node.Parent.Left && nodeColor(sibling.Right) == red {\n\t\tsibling.Right.color = black\n\t\ttree.rotateLeft(node.Parent)\n\t} else if nodeColor(sibling.Left) == red {\n\t\tsibling.Left.color = black\n\t\ttree.rotateRight(node.Parent)\n\t}\n}\n\nfunc nodeColor[K comparable, V any](node *Node[K, V]) color {\n\tif node == nil {\n\t\treturn black\n\t}\n\treturn node.color\n}\n"
  },
  {
    "path": "trees/redblacktree/redblacktree_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage redblacktree\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestRedBlackTreeGet(t *testing.T) {\n\ttree := New[int, string]()\n\n\tif actualValue := tree.Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\n\tif actualValue := tree.GetNode(2).Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n\n\ttree.Put(1, \"x\") // 1->x\n\ttree.Put(2, \"b\") // 1->x, 2->b (in order)\n\ttree.Put(1, \"a\") // 1->a, 2->b (in order, replacement)\n\ttree.Put(3, \"c\") // 1->a, 2->b, 3->c (in order)\n\ttree.Put(4, \"d\") // 1->a, 2->b, 3->c, 4->d (in order)\n\ttree.Put(5, \"e\") // 1->a, 2->b, 3->c, 4->d, 5->e (in order)\n\ttree.Put(6, \"f\") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order)\n\n\tfmt.Println(tree)\n\t//\n\t//  RedBlackTree\n\t//  │           ┌── 6\n\t//  │       ┌── 5\n\t//  │   ┌── 4\n\t//  │   │   └── 3\n\t//  └── 2\n\t//       └── 1\n\n\tif actualValue := tree.Size(); actualValue != 6 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 6)\n\t}\n\n\tif actualValue := tree.GetNode(4).Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 4)\n\t}\n\n\tif actualValue := tree.GetNode(2).Size(); actualValue != 6 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 6)\n\t}\n\n\tif actualValue := tree.GetNode(8).Size(); actualValue != 0 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 0)\n\t}\n}\n\nfunc TestRedBlackTreePut(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\n\tif actualValue := tree.Size(); actualValue != 7 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\tif actualValue, expectedValue := tree.Keys(), []int{1, 2, 3, 4, 5, 6, 7}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttests1 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"e\", true},\n\t\t{6, \"f\", true},\n\t\t{7, \"g\", true},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests1 {\n\t\t// retrievals\n\t\tactualValue, actualFound := tree.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n}\n\nfunc TestRedBlackTreeRemove(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\n\ttree.Remove(5)\n\ttree.Remove(6)\n\ttree.Remove(7)\n\ttree.Remove(8)\n\ttree.Remove(5)\n\n\tif actualValue, expectedValue := tree.Keys(), []int{1, 2, 3, 4}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{\"a\", \"b\", \"c\", \"d\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue := tree.Size(); actualValue != 4 {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, 7)\n\t}\n\n\ttests2 := [][]interface{}{\n\t\t{1, \"a\", true},\n\t\t{2, \"b\", true},\n\t\t{3, \"c\", true},\n\t\t{4, \"d\", true},\n\t\t{5, \"\", false},\n\t\t{6, \"\", false},\n\t\t{7, \"\", false},\n\t\t{8, \"\", false},\n\t}\n\n\tfor _, test := range tests2 {\n\t\tactualValue, actualFound := tree.Get(test[0].(int))\n\t\tif actualValue != test[1] || actualFound != test[2] {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, test[1])\n\t\t}\n\t}\n\n\ttree.Remove(1)\n\ttree.Remove(4)\n\ttree.Remove(2)\n\ttree.Remove(3)\n\ttree.Remove(2)\n\ttree.Remove(2)\n\n\tif actualValue, expectedValue := tree.Keys(), []int{}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Values(), []string{}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 {\n\t\tt.Errorf(\"Got %v expected %v\", empty, true)\n\t}\n\n}\n\nfunc TestRedBlackTreeLeftAndRight(t *testing.T) {\n\ttree := New[int, string]()\n\n\tif actualValue := tree.Left(); actualValue != nil {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\tif actualValue := tree.Right(); actualValue != nil {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, nil)\n\t}\n\n\ttree.Put(1, \"a\")\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\") // overwrite\n\ttree.Put(2, \"b\")\n\n\tif actualValue, expectedValue := tree.Left().Key, 1; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Left().Value, \"x\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tif actualValue, expectedValue := tree.Right().Key, 7; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := tree.Right().Value, \"g\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeCeilingAndFloor(t *testing.T) {\n\ttree := New[int, string]()\n\n\tif node, found := tree.Floor(0); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n\tif node, found := tree.Ceiling(0); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\n\tif node, found := tree.Floor(4); node.Key != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", node.Key, 4)\n\t}\n\tif node, found := tree.Floor(0); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n\n\tif node, found := tree.Ceiling(4); node.Key != 4 || !found {\n\t\tt.Errorf(\"Got %v expected %v\", node.Key, 4)\n\t}\n\tif node, found := tree.Ceiling(8); node != nil || found {\n\t\tt.Errorf(\"Got %v expected %v\", node, \"<nil>\")\n\t}\n}\n\nfunc TestRedBlackTreeIteratorNextOnEmpty(t *testing.T) {\n\ttree := New[int, string]()\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t}\n}\n\nfunc TestRedBlackTreeIteratorPrevOnEmpty(t *testing.T) {\n\ttree := New[int, string]()\n\tit := tree.Iterator()\n\tfor it.Prev() {\n\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t}\n}\n\nfunc TestRedBlackTreeIterator1Next(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\t// │   ┌── 7\n\t// └── 6\n\t//     │   ┌── 5\n\t//     └── 4\n\t//         │   ┌── 3\n\t//         └── 2\n\t//             └── 1\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator1Prev(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(5, \"e\")\n\ttree.Put(6, \"f\")\n\ttree.Put(7, \"g\")\n\ttree.Put(3, \"c\")\n\ttree.Put(4, \"d\")\n\ttree.Put(1, \"x\")\n\ttree.Put(2, \"b\")\n\ttree.Put(1, \"a\") //overwrite\n\t// │   ┌── 7\n\t// └── 6\n\t//     │   ┌── 5\n\t//     └── 4\n\t//         │   ┌── 3\n\t//         └── 2\n\t//             └── 1\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator2Next(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator2Prev(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator3Next(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(1, \"a\")\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator3Prev(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(1, \"a\")\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t}\n\tcountDown := tree.size\n\tfor it.Prev() {\n\t\tkey := it.Key()\n\t\tif actualValue, expectedValue := key, countDown; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcountDown--\n\t}\n\tif actualValue, expectedValue := countDown, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator4Next(t *testing.T) {\n\ttree := New[int, int]()\n\ttree.Put(13, 5)\n\ttree.Put(8, 3)\n\ttree.Put(17, 7)\n\ttree.Put(1, 1)\n\ttree.Put(11, 4)\n\ttree.Put(15, 6)\n\ttree.Put(25, 9)\n\ttree.Put(6, 2)\n\ttree.Put(22, 8)\n\ttree.Put(27, 10)\n\t// │           ┌── 27\n\t// │       ┌── 25\n\t// │       │   └── 22\n\t// │   ┌── 17\n\t// │   │   └── 15\n\t// └── 13\n\t//     │   ┌── 11\n\t//     └── 8\n\t//         │   ┌── 6\n\t//         └── 1\n\tit := tree.Iterator()\n\tcount := 0\n\tfor it.Next() {\n\t\tcount++\n\t\tvalue := it.Value()\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t}\n\tif actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIterator4Prev(t *testing.T) {\n\ttree := New[int, int]()\n\ttree.Put(13, 5)\n\ttree.Put(8, 3)\n\ttree.Put(17, 7)\n\ttree.Put(1, 1)\n\ttree.Put(11, 4)\n\ttree.Put(15, 6)\n\ttree.Put(25, 9)\n\ttree.Put(6, 2)\n\ttree.Put(22, 8)\n\ttree.Put(27, 10)\n\t// │           ┌── 27\n\t// │       ┌── 25\n\t// │       │   └── 22\n\t// │   ┌── 17\n\t// │   │   └── 15\n\t// └── 13\n\t//     │   ┌── 11\n\t//     └── 8\n\t//         │   ┌── 6\n\t//         └── 1\n\tit := tree.Iterator()\n\tcount := tree.Size()\n\tfor it.Next() {\n\t}\n\tfor it.Prev() {\n\t\tvalue := it.Value()\n\t\tif actualValue, expectedValue := value, count; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tcount--\n\t}\n\tif actualValue, expectedValue := count, 0; actualValue != expectedValue {\n\t\tt.Errorf(\"Size different. Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeIteratorBegin(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.Begin()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tfor it.Next() {\n\t}\n\n\tit.Begin()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.Next()\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestRedBlackTreeIteratorEnd(t *testing.T) {\n\ttree := New[int, string]()\n\tit := tree.Iterator()\n\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.End()\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit.End()\n\tif it.node != nil {\n\t\tt.Errorf(\"Got %v expected %v\", it.node, nil)\n\t}\n\n\tit.Prev()\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestRedBlackTreeIteratorFirst(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.First(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 1 || value != \"a\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 1, \"a\")\n\t}\n}\n\nfunc TestRedBlackTreeIteratorLast(t *testing.T) {\n\ttree := New[int, string]()\n\ttree.Put(3, \"c\")\n\ttree.Put(1, \"a\")\n\ttree.Put(2, \"b\")\n\tit := tree.Iterator()\n\tif actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif key, value := it.Key(), it.Value(); key != 3 || value != \"c\" {\n\t\tt.Errorf(\"Got %v,%v expected %v,%v\", key, value, 3, \"c\")\n\t}\n}\n\nfunc TestRedBlackTreeIteratorNextTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// NextTo (empty)\n\t{\n\t\ttree := New[int, string]()\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// NextTo (not found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(0, \"xx\")\n\t\ttree.Put(1, \"yy\")\n\t\tit := tree.Iterator()\n\t\tfor it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// NextTo (found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(2, \"cc\")\n\t\ttree.Put(0, \"aa\")\n\t\ttree.Put(1, \"bb\")\n\t\tit := tree.Iterator()\n\t\tit.Begin()\n\t\tif !it.NextTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Next() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 2 || value != \"cc\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 2, \"cc\")\n\t\t}\n\t\tif it.Next() {\n\t\t\tt.Errorf(\"Should not go past last element\")\n\t\t}\n\t}\n}\n\nfunc TestRedBlackTreeIteratorPrevTo(t *testing.T) {\n\t// Sample seek function, i.e. string starting with \"b\"\n\tseek := func(index int, value string) bool {\n\t\treturn strings.HasSuffix(value, \"b\")\n\t}\n\n\t// PrevTo (empty)\n\t{\n\t\ttree := New[int, string]()\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// PrevTo (not found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(0, \"xx\")\n\t\ttree.Put(1, \"yy\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tfor it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t}\n\n\t// PrevTo (found)\n\t{\n\t\ttree := New[int, string]()\n\t\ttree.Put(2, \"cc\")\n\t\ttree.Put(0, \"aa\")\n\t\ttree.Put(1, \"bb\")\n\t\tit := tree.Iterator()\n\t\tit.End()\n\t\tif !it.PrevTo(seek) {\n\t\t\tt.Errorf(\"Shouldn't iterate on empty tree\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 1 || value != \"bb\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 1, \"bb\")\n\t\t}\n\t\tif !it.Prev() {\n\t\t\tt.Errorf(\"Should go to first element\")\n\t\t}\n\t\tif index, value := it.Key(), it.Value(); index != 0 || value != \"aa\" {\n\t\t\tt.Errorf(\"Got %v,%v expected %v,%v\", index, value, 0, \"aa\")\n\t\t}\n\t\tif it.Prev() {\n\t\t\tt.Errorf(\"Should not go before first element\")\n\t\t}\n\t}\n}\n\nfunc TestRedBlackTreeSerialization(t *testing.T) {\n\ttree := New[string, string]()\n\ttree.Put(\"c\", \"3\")\n\ttree.Put(\"b\", \"2\")\n\ttree.Put(\"a\", \"1\")\n\n\tvar err error\n\tassert := func() {\n\t\tif actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := tree.Keys(), []string{\"a\", \"b\", \"c\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif actualValue, expectedValue := tree.Values(), []string{\"1\", \"2\", \"3\"}; !slices.Equal(actualValue, expectedValue) {\n\t\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Got error %v\", err)\n\t\t}\n\t}\n\n\tassert()\n\n\tbytes, err := tree.ToJSON()\n\tassert()\n\n\terr = tree.FromJSON(bytes)\n\tassert()\n\n\tbytes, err = json.Marshal([]interface{}{\"a\", \"b\", \"c\", tree})\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\n\tintTree := New[string, int]()\n\terr = json.Unmarshal([]byte(`{\"a\":1,\"b\":2}`), intTree)\n\tif err != nil {\n\t\tt.Errorf(\"Got error %v\", err)\n\t}\n\tif actualValue, expectedValue := intTree.Size(), 2; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := intTree.Keys(), []string{\"a\", \"b\"}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tif actualValue, expectedValue := intTree.Values(), []int{1, 2}; !slices.Equal(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestRedBlackTreeString(t *testing.T) {\n\tc := New[string, int]()\n\tc.Put(\"a\", 1)\n\tif !strings.HasPrefix(c.String(), \"RedBlackTree\") {\n\t\tt.Errorf(\"String should start with container name\")\n\t}\n}\n\nfunc benchmarkGet(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Get(n)\n\t\t}\n\t}\n}\n\nfunc benchmarkPut(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Put(n, struct{}{})\n\t\t}\n\t}\n}\n\nfunc benchmarkRemove(b *testing.B, tree *Tree[int, struct{}], size int) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfor n := 0; n < size; n++ {\n\t\t\ttree.Remove(n)\n\t\t}\n\t}\n}\n\nfunc BenchmarkRedBlackTreeGet100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeGet1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeGet10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeGet100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkGet(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreePut100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}]()\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreePut1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreePut10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreePut100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkPut(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeRemove100(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeRemove1000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 1000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeRemove10000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 10000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n\nfunc BenchmarkRedBlackTreeRemove100000(b *testing.B) {\n\tb.StopTimer()\n\tsize := 100000\n\ttree := New[int, struct{}]()\n\tfor n := 0; n < size; n++ {\n\t\ttree.Put(n, struct{}{})\n\t}\n\tb.StartTimer()\n\tbenchmarkRemove(b, tree, size)\n}\n"
  },
  {
    "path": "trees/redblacktree/serialization.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage redblacktree\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/emirpasic/gods/v2/containers\"\n)\n\n// Assert Serialization implementation\nvar _ containers.JSONSerializer = (*Tree[string, int])(nil)\nvar _ containers.JSONDeserializer = (*Tree[string, int])(nil)\n\n// ToJSON outputs the JSON representation of the tree.\nfunc (tree *Tree[K, V]) ToJSON() ([]byte, error) {\n\telements := make(map[K]V)\n\tit := tree.Iterator()\n\tfor it.Next() {\n\t\telements[it.Key()] = it.Value()\n\t}\n\treturn json.Marshal(&elements)\n}\n\n// FromJSON populates the tree from the input JSON representation.\nfunc (tree *Tree[K, V]) FromJSON(data []byte) error {\n\telements := make(map[K]V)\n\terr := json.Unmarshal(data, &elements)\n\tif err == nil {\n\t\ttree.Clear()\n\t\tfor key, value := range elements {\n\t\t\ttree.Put(key, value)\n\t\t}\n\t}\n\treturn err\n}\n\n// UnmarshalJSON @implements json.Unmarshaler\nfunc (tree *Tree[K, V]) UnmarshalJSON(bytes []byte) error {\n\treturn tree.FromJSON(bytes)\n}\n\n// MarshalJSON @implements json.Marshaler\nfunc (tree *Tree[K, V]) MarshalJSON() ([]byte, error) {\n\treturn tree.ToJSON()\n}\n"
  },
  {
    "path": "trees/trees.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package trees provides an abstract Tree interface.\n//\n// 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.\n//\n// Reference: https://en.wikipedia.org/wiki/Tree_%28data_structure%29\npackage trees\n\nimport \"github.com/emirpasic/gods/v2/containers\"\n\n// Tree interface that all trees implement\ntype Tree[V any] interface {\n\tcontainers.Container[V]\n\t// Empty() bool\n\t// Size() int\n\t// Clear()\n\t// Values() []interface{}\n\t// String() string\n}\n"
  },
  {
    "path": "utils/comparator.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage utils\n\nimport \"time\"\n\ntype Comparator[T any] func(x, y T) int\n\n// TimeComparator provides a basic comparison on time.Time\nfunc TimeComparator(a, b time.Time) int {\n\tswitch {\n\tcase a.After(b):\n\t\treturn 1\n\tcase a.Before(b):\n\t\treturn -1\n\tdefault:\n\t\treturn 0\n\t}\n}\n"
  },
  {
    "path": "utils/comparator_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage utils\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestTimeComparator(t *testing.T) {\n\n\tnow := time.Now()\n\n\t// i1,i2,expected\n\ttests := [][]interface{}{\n\t\t{now, now, 0},\n\t\t{now.Add(24 * 7 * 2 * time.Hour), now, 1},\n\t\t{now, now.Add(24 * 7 * 2 * time.Hour), -1},\n\t}\n\n\tfor _, test := range tests {\n\t\tactual := TimeComparator(test[0].(time.Time), test[1].(time.Time))\n\t\texpected := test[2]\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"Got %v expected %v\", actual, expected)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "utils/utils.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// Package utils provides common utility functions.\n//\n// Provided functionalities:\n// - sorting\n// - comparators\npackage utils\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// ToString converts a value to string.\nfunc ToString(value interface{}) string {\n\tswitch value := value.(type) {\n\tcase string:\n\t\treturn value\n\tcase int8:\n\t\treturn strconv.FormatInt(int64(value), 10)\n\tcase int16:\n\t\treturn strconv.FormatInt(int64(value), 10)\n\tcase int32:\n\t\treturn strconv.FormatInt(int64(value), 10)\n\tcase int64:\n\t\treturn strconv.FormatInt(value, 10)\n\tcase uint8:\n\t\treturn strconv.FormatUint(uint64(value), 10)\n\tcase uint16:\n\t\treturn strconv.FormatUint(uint64(value), 10)\n\tcase uint32:\n\t\treturn strconv.FormatUint(uint64(value), 10)\n\tcase uint64:\n\t\treturn strconv.FormatUint(value, 10)\n\tcase float32:\n\t\treturn strconv.FormatFloat(float64(value), 'g', -1, 64)\n\tcase float64:\n\t\treturn strconv.FormatFloat(value, 'g', -1, 64)\n\tcase bool:\n\t\treturn strconv.FormatBool(value)\n\tdefault:\n\t\treturn fmt.Sprintf(\"%+v\", value)\n\t}\n}\n"
  },
  {
    "path": "utils/utils_test.go",
    "content": "// Copyright (c) 2015, Emir Pasic. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage utils\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestToStringInts(t *testing.T) {\n\tvar value interface{}\n\n\tvalue = int8(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = int16(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = int32(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = int64(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = rune(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestToStringUInts(t *testing.T) {\n\tvar value interface{}\n\n\tvalue = uint8(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = uint16(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = uint32(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = uint64(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = byte(1)\n\tif actualValue, expectedValue := ToString(value), \"1\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestToStringFloats(t *testing.T) {\n\tvar value interface{}\n\n\tvalue = float32(1.123456)\n\tif actualValue, expectedValue := ToString(value), \"1.123456\"; !strings.HasPrefix(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\tvalue = float64(1.123456)\n\tif actualValue, expectedValue := ToString(value), \"1.123456\"; !strings.HasPrefix(actualValue, expectedValue) {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n\nfunc TestToStringOther(t *testing.T) {\n\tvar value interface{}\n\n\tvalue = \"abc\"\n\tif actualValue, expectedValue := ToString(value), \"abc\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\tvalue = true\n\tif actualValue, expectedValue := ToString(value), \"true\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n\n\ttype T struct {\n\t\tid   int\n\t\tname string\n\t}\n\n\tif actualValue, expectedValue := ToString(T{1, \"abc\"}), \"{id:1 name:abc}\"; actualValue != expectedValue {\n\t\tt.Errorf(\"Got %v expected %v\", actualValue, expectedValue)\n\t}\n}\n"
  }
]