GithubHelp home page GithubHelp logo

rrb.rhm's People

Contributors

oxson avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

rrb.rhm's Issues

Add a 'tail' optimization

Store the last node's-worth of elements separately from the tree itself to allow constant time access and update near the end of the vector. Clojure does this. Nicolas Stucki's version includes a generalized notion of a tail called a 'focus' or 'display', that moves the constant-time accessible portion to most recently accessed. So operations near the same portion of the tree that has been touched most recently will be fast. Do we want this? Maybe.

macro-ize `fun leaf(args, ...)`

per Matthew's feedback

At the point where you worry about performance, the leaf function may
need to be converted into a macro that constructs a vector more
directly. Right now, leaf will build up a list to receive its
arguments, and then have to apply the vec function to that list.
And then the vec function will also receive the arguments in a fresh
list and apply the #{vector-immutable} function. It's possible that
inlining at the Racket or Chez Scheme level works better than I think,
but I don't think the intermediate list allocations will be optimized
away.

  • in utils.rhm, don't wrap racket's vector->immutable-vector in a rhombus function, just export and rename to vec
  • make leaf a macro instead of a function

Implement `Tree(...).concat(t :: Tree)`

The main structure of the code is there, now, but it is not yet working as intended in some ways. The result of some_tree.concat(other_tree).to_list() will always be as expected, but there are performance issues lurking and a lack of thorough testing involving trees of varied sizes as well as trees created through complex-ish series of operations including concats, appends, sets, etc.

  • fix #5 may not need fixing, see comments on #5
  • needs more thorough testing
    • #7
    • randomized tests
    • test very large trees

Implement full List api

as proposed in racket/rhombus-prototype#351

  • method get(index)
  • method set(index, element)
  • method add(element) # Adds to the end of the list
  • method insert(index, element)
  • method remove(element) # Removes first occurrence of element from list
  • method removeAt(index)
  • method sublist(start, end) # Returns a view

Avoid setting size arrays on leftwise-dense nodes during concatenation

leftwise-dense nodes should not have sizes arrays. Currently all nodes created via concatenation except leaf nodes end up with sizes arrays. This means some future operations will take the slow path that should not. Example:

> check: Tree(leaf(& List.iota(32)), 32, 0).concat(Tree(leaf(& List.iota(32)), 32, 0)).root.sizes
         ~is #false
    
check: failed
  got: Array(32, 64)
  expected: #false

Note, though, that only the nodes along the join path of the new tree will get sizes arrays always set. So, for example:

> def (t, l, r):
      def l:
        for values(t = Tree()):
          each i: List.iota(32^3)
          t.add(i)
      def r:
        for values(t = Tree()):
          each i: List.iota(32^3)
          t.add(i + 32^3)
      values(l.concat(r), l, r)
      
> values(l.balanced, r.balanced)
#true
#true
> t.root.balanced
#false
> t.root.size
2
> values(t.root.get(0).balanced, t.root.get(1).balanced)
#false
#false
> for values(balanced = #true):
    each i: 0 .. t.root.get(0).size - 1
    balanced && t.root.get(0).get(i).balanced
    
#true
> t.root.get(t.root.size - 1).balanced
#false
> for values(balanced = #true):
    each i: 1 .. t.root.get(1).size
    balanced && t.root.get(1).get(i).balanced
    
#true
> t.root.get(1).get(0).balanced
#false```

Get rid of parameters

For ease of testing, it's nice to be able to change the branch factor / max width of a tree (it's much easier to write out a manual test for a 2 or 4-way branching tree than a 32-way branching tree), but in the end, this configuration capability is probably not needed and also probably negatively affects performance. What Clojure does is maintain separate copies of the code where one is parameterized and one is not (see here). We could do something like that, if maintaining parameterized capability is desired (maybe for future dev work / testing, maybe there is some actual production code use case)

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.