From 348b9201a63d8dff7c5a8e21252e0450cdc72b23 Mon Sep 17 00:00:00 2001 From: Eric Myhre Date: Fri, 24 Aug 2018 12:24:34 +0200 Subject: [PATCH] Start a readme for this research project. Right now this is mostly this is to document the behavior of interface-keyed maps. I suspect some of those caveats might be non-obvious to a lot of folks. --- _rsrch/cidiface/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 _rsrch/cidiface/README.md diff --git a/_rsrch/cidiface/README.md b/_rsrch/cidiface/README.md new file mode 100644 index 0000000..d221a5d --- /dev/null +++ b/_rsrch/cidiface/README.md @@ -0,0 +1,39 @@ +What golang Kinds work best to implement CIDs? +============================================== + +There are many possible ways to implement CIDs. This package explores them. + +- Option A: CIDs as a struct; multihash as bytes. +- Option B: CIDs as a string. +- Option C: CIDs as an interface with multiple implementors. +- Option D: CIDs as a struct; multihash also as a struct or string. + +There's a couple different criteria to consider: + +- We want the best performance when operating on the type (getters, mostly); +- We want to minimize the number of memory allocations we need; +- We want types which can be used as map keys, because this is common. + +The priority of these criteria is open to argument, but it's probably +mapkeys > minalloc > anythingelse. +(Mapkeys and minalloc are also quite entangled, since if we don't pick a +representation that can work natively as a map key, we'll end up needing +a `KeyRepr()` method which gives us something that does work as a map key, +an that will almost certainly involve a malloc itself.) + + +Discoveries +----------- + +### using interfaces as map keys forgoes a lot of safety checks + +Using interfaces as map keys pushes a bunch of type checking to runtime. +E.g., it's totally valid at compile time to push a type which is non-comparable +into a map key; it will panic at *runtime* instead of failing at compile-time. + +There's also no way to define equality checks between implementors of the +interface: golang will always use its innate concept of comparison for the +concrete types. This means its effectively *never safe* to use two different +concrete implementations of an interface in the same map; you may add elements +which are semantically "equal" in your mind, and end up very confused later +when both impls of the same "equal" object have been stored.