Implement stream isolation backend logic for proposal 171

Part of proposal 171 will be looking at two streams and determining whether or not they can share a circuit. In order to make this efficient, we shouldn't do it as an O(n ** 2) operation, however: instead of comparing each stream with every other stream on a candidate circuit, we should:

  • annotate the circuit with a description of what streams may be attached to it,
  • compare the circuit's rules to any new stream we want to attach to the circuit,
  • and update the rules as needed when we attach a new stream.

To do this efficiently, we'll need to design some data structures to represent a stream's isolation requirements and the isolation a circuit can provide. We'll need some compare and update functions.