utils.datastructures: Implement OrderedIndex and StrictOrderedIndex
utils.datastructures: Implement OrderedIndex and StrictOrderedIndex

OrderedIndex is basically an OrderedDict but with set semantics, i.e.
keys are derived from values.  The key function can be passed to
OrderedIndex constructor; the default is id().

StrictOrderedIndex is a variant of OrderedIndex which raises an
exception when an attempt to add a duplicate item is made.

This commit also reorganizes the code, so that OrderedSet and
OrderedIndex share the base implementation of an ordered set.
OrderedSet now has explicit sequence semantics.

edgedb/edgedb,edgedb/edgedb,edgedb/edgedb