• Eric Myhre's avatar
    More new map implementation. · 631a8e30
    Eric Myhre authored
    Includes duplicate key checks that were previously missing.
    
    Overall, checks many more invariants.  There are now "*_ValueAssembler"
    types involved in both the 'free'/generic implementation, and the
    codegen implementation: in both cases, it's needed for several tasks,
    mostly revolving around the "Done" method (or anything else that causes
    doneness, e.g. any of the scalar "Assign*" methods):
    
    - to make sure the map assembly doesn't move on until the value
      assembly is finished!  Need to do this to make it possible to
      maintain any other invariant over the whole tree!
    - to do state machine keeping on the map assembler
    - to do any integrity checks that the map itself demands
    - and in some cases, to actually commit the entry itself (although
      in some cases, pointer funtimes at key finish time are enough).
    
    The introduction of these '*_KeyAssembler' and '*_ValueAssembler' types
    is somewhat frustrating, because they add more memory, more vtable
    interactions (sometimes; in codegen, the compiler can inline them out),
    and just plain more SLOC.  Particularly irritatingly, they require a
    pointer back to their parent assembler... even though in practice,
    they're always embedded *in* that same structure, so it's a predictable
    offset from their own pointer.  But I couldn't easily seem to see a
    way around that (shy of using unsafe or other extreme nastiness), so,
    I'm just bitting the bullet and moving on with that.
    
    (I even briefly experimented with using type aliases to be able to
    decorate additional methods contextually onto the same struct memory,
    hoping that I'd be able to choose which type's set of methods I apply.
    (I know this is possible internally -- if one writes assembler, that's
    *what the calls are like*: you grab the function definition from a
    table of functions per type, and then you apply it to some memory!)
    This would make it possible to put all the child assembler functions
    on the same memory as the parent assembler that embeds them, and thus
    save us the cyclic pointers!  But alas, no.  Attempting to do this will
    run aground on "duplicate method" errors quite quickly.  Aliases were
    not meant to do this.)
    
    There's some new tests, in addition to benchmarks.
    
    'plainMap', destined to be part of the next version of the 'ipldfree'
    package, is now complete, and passes tests.
    
    A couple key tests are commented out, because they require a bump in
    version of the go-wish library, and I'm going to sort that in a
    separate commit.  They do pass, though, otherwise.
    
    Some NodeStyle implementations are introduced, and now those are the
    way to get builders for those nodes, and all the tests and benchmarks
    use them.  The placeholder 'NewBuilder*' methods are gone.
    
    There are some open questions about what naming pattern to use for
    exporting symbols for NodeStyles.  Some comments regard this, but it's
    a topic to engage in more earnest later.
    
    Benchmarks have been renamed for slightly more consistency and an eye
    towards additional benchmarks we're likely to add shortly.
    
    Some new documentation file are added!  These are a bit ramshackle,
    because they're written as an issue of note occurs to me, but there are
    enough high-level rules that should be held the same across various
    implementations of Node and NodeAssembler that writing them in a doc
    outside the code began to seem wise.
    631a8e30
map_test.go 4.12 KB