Skip to content

datamodel Length() not usable with lazy nodes (e.g. ADLs) #531

@aschmahmann

Description

@aschmahmann

Noticed while discovering ipfs/go-unixfsnode#54

The contract on node.Length() is

// Length returns the length of a list, or the number of entries in a map,
// or -1 if the node is not of list nor map kind.
Length() int64

This means that if there is any sort of lazy loading or computation involved in working with a node that is definitely a list or map that there is nothing valid to return.

  1. Could return -1 but that's a contract violation
  2. Could return some number (e.g. go-unixfsnode's HAMT returns the largest number of entries it can confirm https://github.com/ipfs/go-unixfsnode/blob/364a5496925b291900d67c35b8b898e1a30b7f0a/hamt/shardeddir.go#L262-L289), but that's also a contract violation since the user expects "the number of entries in a map" not "some number <= the number of entries in a map" and the application has no indication that anything has gone wrong.

I suspect the options here are:

  1. Change Length to return an error
  2. Change the contract to allow -1 to mean any type of error
  3. Add a new function (name TBD) that does return an error and deprecate Length

While 2 seems the easiest, it has the ability to break a bunch of code without people noticing. Simple compile-time checked fixes like 1 seem a safer option.

Whether 1 or 3 is preferred seems like a matter of taste.


Note: the other functions on the Node interface which could potentially run into a similar issue are Kind(), IsAbsent(), and IsNull() However, it seems like these are less likely to be lazily constructed than Length and therefore less likely to be a problem.

Similarly, the map and list iterators can return errors once they're in use (and they can be checked in advance with Kind()) and so are also less problematic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions