Git Product home page Git Product logo

flat-tree's People

Contributors

bltavares avatar dependabot-preview[bot] avatar khernyo avatar mafintosh avatar pierd avatar prettymuchbryce avatar ralphtheninja avatar ttiurani avatar yoshuawuyts avatar zhouhanseng 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

flat-tree's Issues

Is uncle used?

I noticed that uncle was implemented, which isn't part of the js api. Is that used somewhere?

Algorithmically quite slow

I decided to look at the generated assembly for the left_child function (inlining everything it calls):

example::left_child:
  push rbp
  mov rbp, rsp
  xor eax, eax
  test dil, 1
  jne .LBB0_2
  mov rdx, rdi
  pop rbp
  ret
.LBB0_2:
  mov rdx, rdi
  mov rcx, rdx
.LBB0_3:
  shr rcx
  add rax, 1
  test dl, 2
  mov rdx, rcx
  jne .LBB0_3
  test rax, rax
  je .LBB0_5
  lea ecx, [rax + 1]
  shr rdi, cl
  add rdi, rdi
  lea rdx, [rax - 1]
  mov ecx, eax
  shl rdi, cl
  mov esi, 1
  mov ecx, edx
  shl rsi, cl
  mov eax, 1
  add rsi, -1
  or rdi, rsi
  mov rdx, rdi
  pop rbp
  ret
.LBB0_5:
  mov eax, 1
  mov rdx, rdi
  pop rbp
  ret

By rewriting it to store each level in its entirety consecutively (level 1, then 2, then 3, etc), I got this (since then changed, will update later, but wasn't much longer):

example::left_child:
  push rbp
  mov rbp, rsp
  lea rax, [rdi + rdi]
  add rax, -1
  pop rbp
  ret

I understand that the algorithm is taken from the JS project, but I still think that this algorithm is quite slow...

Use `id` instead of `index`

It seems to me that the data referred to as index is not really an index. At least it's not the node index when building the merkle-tree. It's a bit confusing when the nodes are stored in a flat data structure (e.g., a list).

When building the merkle-tree, there is an inherent ordering which is the order in which each hash is computed (using this order requires the least amount of memory to build the merkle-tree):

  1. first data block is received, its hash is computed (A)
  2. second data block is received, its hash is computed (B)
  3. hash of (AB) is computed (C)
  4. third data block is received, hashes computed (D)
  5. fourth data block is received, hashes computed (E)
  6. hash of (DE) is computed (F)
  7. hash of (CF) is computed (G)
    ...

The index for the above hashes in the flat-tree are the following:

  • A: 0
  • B: 2
  • C: 1
  • D: 4
  • E: 6
  • F: 5
  • G: 3

Maybe there is a reason for using index to refer to these nodes, but I could not find one. So, if there is no specific reason for this name, I propose to use id or maybe position instead.

consider removing xyz_with_depth() from the api?

I have an index, lets say index = 44 and I want the offset, so I call offset(44). Does it even make sense to call offset_with_depth(44, 4)?

I suspect these functions are there because rust doesn't have default values for function parameters, which is the same thing for functions in c.

Maybe all xyz_with_depth() should be local only?

Same goes for .sibling(), .parent() etc

More concretely, does a calling lib ever pass in depth explicitly?

error[E0554]: #![feature] may not be used on the stable release channel

When compiling hypercore I get the following error:

error[E0554]: #![feature] may not be used on the stable release channel
 --> /Users/bryce/.cargo/registry/src/github.com-1ecc6299db9ec823/flat-tree-3.3.0/src/lib.rs:2:1
  |
2 | #![feature(external_doc)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
cargo --version
cargo 1.28.0 (96a2c7d16 2018-07-13)

I'm not very familiar with Rust, is it implied that I should not be using the stable release channel?

cargo test fails

I get the following output

error[E0308]: mismatched types
    --> /home/lms/.cargo/registry/src/github.com-1ecc6299db9ec823/clippy_lints-0.0.194/src/loops.rs:1801:48
     |
1801 |         ty::TyArray(_, n) => (0..=32).contains(n.val.to_raw_bits().expect("array length")),
     |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |                                                |
     |                                                expected reference, found u128
     |                                                help: consider borrowing here: `&n.val.to_raw_bits().expect("array length")`
     |
     = note: expected type `&_`
                found type `u128`

error[E0308]: mismatched types
   --> /home/lms/.cargo/registry/src/github.com-1ecc6299db9ec823/clippy_lints-0.0.194/src/regex.rs:213:56
    |
213 |                         str_span(expr.span, *e.span(), offset),
    |                                                        ^^^^^^ expected usize, found u16

error[E0308]: mismatched types
   --> /home/lms/.cargo/registry/src/github.com-1ecc6299db9ec823/clippy_lints-0.0.194/src/regex.rs:221:56
    |
221 |                         str_span(expr.span, *e.span(), offset),
    |                                                        ^^^^^^ expected usize, found u16

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `clippy_lints`.

I made rustup update earlier today, not sure if it has anything to do with that

`.children()` is off

The following isn't working right now:

flat_tree::children(9) == (8, 10)

Instead it's returning (2, 4)

Return more Option types.

Some cases to consider:

  • calling .prev() on the iterator while at the left nodes
  • calling left-child / right-child of a leaf node
  • calling left-span / right-span of a leaf node

I'm thinking we should perhaps return the Option type more often in both FlatTree and the Iterator structs.

improve readme docs

We can probably drop the API header, but also bring it closer in line with the rest of the repos.

left_child_with_depth and right_child_with_depth

If it turns out that left_child_with_depth and right_child_with_depth can be private, there's a few things we could change after that

  1. If they aren't used internally (which I suspect they aren't), then we could merge them, so body of left_child_with_depth is moved to left_child (and similarly for right_child)
  2. The depth == 0 check is no longer needed, since this only happens for even indices

So

pub fn left_child_with_depth(i: usize, depth: usize) -> Option<usize> {
  if is_even(i) {
    None
  } else if depth == 0 {
    Some(i)
  } else {
    Some(index(
      depth - 1,
      offset_with_depth(i, depth) << 1,
    ))
  }
}

pub fn left_child(i: usize) -> Option<usize> {
  left_child_with_depth(i, depth(i))
}

Could be

pub fn left_child(i: usize) -> Option<usize> {
  if is_even(i) {
    None
  } else {
    let d = depth(i)
    Some(index(
      d - 1,
      offset_with_depth(i, d) << 1,
    ))
  }
}

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.