1. 01 Jul, 2021 1 commit
    • Daniel Martí's avatar
      fluent/quip: remove in favor of qp · b7347f19
      Daniel Martí authored
      After experimenting with quip and qp for a few months, we seem to agree
      that qp is a bit nicer to use. Remove quip, since it's largely redundant
      going forward.
      
      Since the qp docs referenced quip, redo that to stand on its own ground.
      b7347f19
  2. 25 Feb, 2021 1 commit
    • Eric Myhre's avatar
      Introduce LinkSystem. · a1482fe2
      Eric Myhre authored
      This significantly reworks how linking is handled.
      
      All of the significant operations involved in storing and loading
      data are extracted into their own separate features, and the LinkSystem
      just composes them.  The big advantage of this is we can now add as
      many helper methods to the LinkSystem construct as we want -- whereas
      previously, adding methods to the Link interface was a difficult
      thing to do, because that interface shows up in a lot of places.
      
      Link is now *just* treated as a data holder -- it doesn't need logic
      attached to it directly.  This is much cleaner.
      
      The way we interact with the CID libraries is also different.
      We're doing multihash registries ourselves, and breaking our direct
      use of the go-multihash library.  The big upside is we're now using
      the familiar and standard hash.Hash interface from the golang stdlib.
      (And as a bonus, that actually works streamingly; go-mulithash didn't.)
      However, this also implies a really big change for downstream users:
      we're no longer baking as many hashes into the new multihash registry
      by default.
      a1482fe2
  3. 18 Jan, 2021 1 commit
    • Daniel Martí's avatar
      fluent: add qp, a different spin on quip · 39ca6c26
      Daniel Martí authored
      This is what I came up with, building on top of Eric's quip. I don't
      want to waste too much time naming this, and I like two-letter package
      names in place of dot-imports, so "qp" seems good enough for now. They
      are the "strong" consonants when one says "Quick iPld".
      
      First, move the benchmarks comparing all fluent packages to the root
      fluent package, to keep things a bit more tidy.
      
      Second, make all the benchmarks report their allocation stats, without
      having to always remember to use the -benchmem flag.
      
      Third, add a qp benchmark.
      
      Fourth, notice a couple of potential bugs in the quip benchmarks, and
      add TODOs for them.
      
      Finally, add the qp API. It differs from quip in a few external ways:
      
      1) No error pointers. Instead, it uses panics which are recovered at the
         top-level API layer. This reduces verbosity, removes the "forgot to
         handle an error" type of mistake, and does not affect performance
         thanks to the defers being statically allocated in the stack.
      
      2) Supposed better composition. For example, one can use MapEntry along
         with Map to have a map inside another map. In contrast, quip requires
         either an extra layer of func literals, or extra API like
         AssignMapEntryString.
      
      3) Thanks to the points above, the API is significantly smaller. Note
         that some helper APIs like Bool are missing, but even when added, qp
         should expose about half the API funcs taht quip does.
      
      This is the first proof of concept. I'll probably finish adding the rest
      of the API helpers when I find the first use case for qp.
      
      Benchmark numbers, with perflock and benchstat on my i5-8350u laptop:
      
      	name                              time/op
      	Quip-8                            1.39µs ± 1%
      	QuipWithoutScalarFuncs-8          1.42µs ± 2%
      	Qp-8                              1.46µs ± 2%
      
      	name                              alloc/op
      	Quip-8                              912B ± 0%
      	QuipWithoutScalarFuncs-8            912B ± 0%
      	Qp-8                                912B ± 0%
      
      	name                              allocs/op
      	Quip-8                              18.0 ± 0%
      	QuipWithoutScalarFuncs-8            18.0 ± 0%
      	Qp-8                                18.0 ± 0%
      39ca6c26
  4. 08 Jan, 2021 1 commit
    • Eric Myhre's avatar
      quip: flesh out more methods for scalars, generally polish. · 4f7dfa72
      Eric Myhre authored
      Lots of individual things:
      
      - removed the "Begin*" functions; no need to expose that kind of raw
        operation when the callback forms are zero-cost.
      
      - renamed functions for consistent "Build" vs "Assemble".
      
      - added "Assign*" functions for all scalar kinds, which reduces the
        usage of "AbsorbError" (but also, left AbsorbError in).
      
      - renamed the ListEntry/MapEntry functions to also have "Assemble*"
        forms (still callback style).
      
      - while also adding Assign{Map|List}Entry{Kind} functions (lets you
        get rid of another callback whenever the value is a scalar).
      
      - added Assign{|MapEntry|ListEntry} functions, which shell out to
        fluent.Reflect for even more convenience (at the cost of performance).
      
      - moved higher level functions like CopyRange to a separate file.
      
      - new benchmark, for the terser form of working with scalars.
        (It's also evidently slightly faster, because fewer small function
        calls.  Slightly surprising considering how much inlining we might
        expect, but, huh.  Alright, surprise bonus; acceptable.)
      
      - example function updated to use the terser form.
      
      With these terseness improvements to handling of scalars, the overall
      SLOC count for using the quip system is now exactly on par with fluent.
      
      Varations on map key arguments (which could be PathSegment or even
      Node, in addition to string) still aren't made available this.
      Perhaps that's just okay.  If you're really up some sort of creek
      where you need that, you can still just use the
      MapAssembler.AssembleKey system directly, which can do everything.
      4f7dfa72
  5. 02 Jan, 2021 1 commit