Code Monkey home page Code Monkey logo

generic's Introduction

Generic Data Structures

Test Workflow Go Report Card Go Reference MIT License

This package implements some generic data structures.

  • array2d: a 2-dimensional array.
  • avl: an AVL tree.
  • bimap: a bi-directional map; a map that allows lookups on both keys and values.
  • btree: a B-tree.
  • cache: a wrapper around map[K]V that uses a maximum size and evicts elements using LRU when full.
  • hashmap: a hashmap with linear probing. The main feature is that the hashmap can be efficiently copied, using copy-on-write under the hood.
  • hashset: a hashset that uses the hashmap as the underlying storage.
  • heap: a binary heap.
  • interval: an interval tree, implemented as an augmented AVL tree.
  • list: a doubly-linked list.
  • mapset: a set that uses Go's built-in map as the underlying storage.
  • multimap: an associative container that permits multiple entries with the same key.
  • queue: a First In First Out (FIFO) queue.
  • rope: a generic rope, which is similar to an array but supports efficient insertion and deletion from anywhere in the array. Ropes are typically used for arrays of bytes, but this rope is generic.
  • prope: a persistent version of the rope, which allows for keeping different versions of the rope with only a little extra time or memory.
  • stack: a LIFO stack.
  • trie: a ternary search trie.
  • ulist: an un-rolled doubly-linked list.

See each subpackage for documentation and examples. The top-level generic package provides some useful types and constraints. See DOC.md for documentation.

Contributing

If you would like to contribute a new feature, please let me know first what you would like to add (via email or issue tracker). Here are some ideas:

  • New data structures (bloom filters, graph structures, concurrent data structures, adaptive radix tree, or other kinds of search trees).
  • Benchmarks, and optimization of the existing data structures based on those benchmarks. The hashmap is an especially good target.
  • Design and implement a nice iterator API.
  • Improving tests (perhaps we can use Go's new fuzzing capabilities).

generic's People

Contributors

anandvarma avatar angusgmorrison avatar applejag avatar atlasgurus avatar dans-stuff avatar forbearing avatar hhhhhhhhhn avatar jan-dubsky avatar nchengyeeshen avatar shawc71 avatar testwill avatar yangtau avatar yoursunny avatar zyedidia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

generic's Issues

Trie Remove implementation is inefficient

The implementation of (*Trie).Remove causes the trie to become steadily less efficient as more keys are deleted.

By inserting a tombstone instead of recursively deleting unused nodes, many redundant nodes may remain in place. This increases the the worst-case time for a search miss from logarithmic to linear.

For example, imagine our trie contains only the key "APPLE". We call, t.Remove("APPLE"), which replaces the value at the final "E" character with a tombstone. If we now search for "APPLES", we must check the nodes "A", "P", "P", "L" and "E", before finding that "APPLES" is not in the trie, since none of these nodes were deleted when "APPLE" was removed.

What should happen in this scenario is that we delete "APPLE", causing all of its nodes to be recursively deleted from the trie. Now when we search for "APPLES", we immediately miss when looking up the letter "A".

Please correct me if there's a use case for the tombstone that I've misunderstood. Otherwise I'm happy to open a PR to fix this.

Feature Request - Generic Algorithms

Any Generic Types library needs an Algorithmic Generics library.

I propose adding in AbstractDataTypes(ADT) as a Type Parameter with internal (K,V) types and then accept an Algorithm Type Parameter which can successfully call on ADT iterators.

This concept is simply an extension of C++ generics and corollaries can be found I believe in the STL library.

Trie is broken

func TestKeys(t *testing.T) {
	tr := trie.New[int]()
	tr.Put("topic1", 1)
	tr.Put("topic2", 2)
	assert.Equal(t, []string{"topic1", "topic2"}, tr.Keys())
}

The result is

--- FAIL: TestKeys (0.00s)
    trie_test.go:68: 
                Error Trace:    trie_test.go:68
                Error:          Not equal: 
                                expected: []string{"topic1", "topic2"}
                                actual  : []string{"topic1", "topi2"}
                            
                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -2,3 +2,3 @@
                                  (string) (len=6) "topic1",
                                - (string) (len=6) "topic2"
                                + (string) (len=5) "topi2"
                                 }
                Test:           TestKeys
FAIL
exit status 1
FAIL    github.com/zhulik/go-eventbus/trie      0.004s

Btree Each() need exit

Btree Each function needs to set the exit, otherwise it can't exit manually, it has to force the loop to finish.

Like this, Exit the loop when the callback fn returns true.
func (t *Tree[K, V]) Each(fn func(key K, val V) bool)

More features for `mapset`

Hello,

We have our own implementation of sets in our codebase (which is not relying on generics), and we would like to switch to a generics aproach for this.

The mapset package looks great but we can't use this as is without adding more features.
Here are some methods that we use regularly and that we would need.

// returns items of the set in a slice
func (s Set[K]) Items() []K

// creates a new set from a slice
func FromSlice[K]([]K) Set[K]

func (s Set[K]) Copy() Set[K]

// set with all items that are in both s and other
func (s Set[K]) Intersection(other Set[K]) Set[K]

// set with all items that are in either s or other
func (s Set[K]) Union(other Set[K]) Set[K]

// all items that are in s but not in other
func (s Set[K]) Substraction(other Set[K]) Set[K]

// are the sets equal
func (s Set[K]) Equals(other Set[K]) bool

// and maybe this one
// returns true if all items of other are included in s
func (s Set[K]) IsSuperSet(other Set[K]) bool

If you think that we should integrate those methods, I can take care of creating some PRs for this.

Cheers

Trie implementation is incompatible with non-ASCII characters

The current trie implementation fails for Unicode characters greater than 1 byte in size. This is because it indexes string keys directly rather than first converting strings to rune slices, wherein each rune represents a whole Unicode character.

This occurs in both the get and put methods.

If you agree this is a problem, I'm happy to open a PR.

Add FIFO Queue

Hi @zyedidia, I'd like to contribute a simple FIFO queue.

Using doubly-linked list nodes defined in list package it should be quick to add a simple First In First Out (FIFO) queue.

What are your thoughts?

Gomarkdoc does not support go 1.18

Method receivers with type parameters are rendered as BADRECV in the generated documentation. There are also some other problems with links.

Improving/Measure performance of hashmap

There exists different algorithm to handle collisions for the linear probing strategy. One interesting an practicable way is the Robin Hood hashing.

good illustration:
https://programming.guide/robin-hood-hashing.html

c++ implementation:
https://github.com/Tessil/robin-map/blob/master/include/tsl/robin_hash.h

I created a pull request as a first draft: #41

What do you think about such performance issues? It is still an open task to measure it. What do you think about to create a performance measure tooling like: https://tessil.github.io/2016/08/29/benchmark-hopscotch-map.html in golang? Or do you know good tools?

Add Persistent Rope

Hello @zyedidia, I was thinking of contributing a persistent rope to the project.

Does it fit in to the project? There is already a rope, but adding immutable methods to it would cause undefined behavior if you used them with the mutable ones.

Thank you for your time!

package "constraints" has been removed since go 1.18 rc1

running into this problem

go get -u github.com/zyedidia/generic
github.com/zyedidia/generic imports
	constraints: package constraints is not in GOROOT (/usr/local/go/src/constraints)

I confirmed the package is not in the src path.

Then I found the constraints will be removed in 1.18
see golang/go#50792

prope is not included in release 1.21.1

Attempting to run

go get github.com/zyedidia/generic/prope

Results in the following error:

go: module github.com/zyedidia/generic@upgrade found (v1.2.1), but does not contain package github.com/zyedidia/generic/prope

I can retrieve the entire package with

go get github.com/zyedidia/generic

But when I try to use propfe with
package main

import (
"github.com/zyedidia/generic/prope"
)

func main() {
data := "=ℇ∞∏"
runes := []rune(data)
r := prope.Newrune
r.Insert(1, []rune{32})
}

I get the error message

main.go:7:2: no required module provides package github.com/zyedidia/generic/prope; to add it:
go get github.com/zyedidia/generic/prope


If I download the 1.21.1 release directly from GitHub I can see that the distribution archive does not contain the `prope` package. 
 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.