Retrieve sorted nodes/edges from GraphJSON (#1015)

As discussed in #1004, we want to be able to package metadata with a
graph's nodes and edges. We can do this much more compactly if we store
the metadata as an array, ordered by the corresponding node/edge
address, rather than storing a map. The disadvantage is that clients
then need to manually sort the graph addresses to deserialize.

This commit adds public methods that allow a client to efficiently
retrieve the sorted addresses from the GraphJSON (where they are already
serialized). This behavior is tested. Note that we appropriately don't
allow clients to peek and directly depend on the exact representation of
GraphJSON, we just promise that sorted address retrieval is possible.

Test plan: Unit tests added (and I verified that breaking the sorting
will fail the test).
This commit is contained in:
Dandelion Mané 2019-02-14 12:22:56 -07:00 committed by GitHub
parent b51491ce1a
commit 7bc0d6956a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 0 deletions

View File

@ -904,3 +904,35 @@ export function edgeToParts(
const dstParts = NodeAddress.toParts(edge.dst); const dstParts = NodeAddress.toParts(edge.dst);
return {addressParts, srcParts, dstParts}; return {addressParts, srcParts, dstParts};
} }
/*
* When JSON-serialized, the graph has all of the edges in sorted
* order. This makes it possible to compactly represent metadata
* associated with every edge without needing to duplicate the
* (lengthy) edge addresses.
* This method makes it possible for consumers of Graph to package
* metadata in the same way, without needing to manually re-sort the
* edges.
*/
export function sortedEdgeAddressesFromJSON(
json: GraphJSON
): $ReadOnlyArray<EdgeAddressT> {
const {edges} = fromCompat(COMPAT_INFO, json);
return edges.map((x) => EdgeAddress.fromParts(x.address));
}
/*
* When JSON-serialized, the graph has all of the nodes in sorted
* order. This makes it possible to compactly represent metadata
* associated with every node without needing to duplicate the
* (lengthy) node addresses.
* This method makes it possible for consumers of Graph to package
* metadata in the same way, without needing to manually re-sort the
* nodes.
*/
export function sortedNodeAddressesFromJSON(
json: GraphJSON
): $ReadOnlyArray<NodeAddressT> {
const {nodes} = fromCompat(COMPAT_INFO, json);
return nodes.map((x) => NodeAddress.fromParts(x));
}

View File

@ -16,6 +16,8 @@ import {
edgeToString, edgeToString,
edgeToStrings, edgeToStrings,
edgeToParts, edgeToParts,
sortedEdgeAddressesFromJSON,
sortedNodeAddressesFromJSON,
} from "./graph"; } from "./graph";
import {advancedGraph} from "./graphTestUtil"; import {advancedGraph} from "./graphTestUtil";
@ -1446,4 +1448,21 @@ describe("core/graph", () => {
expect(edgeToParts(edge)).toEqual(expected); expect(edgeToParts(edge)).toEqual(expected);
}); });
}); });
it("sortedEdgeAddressesFromJSON", () => {
const json = advancedGraph()
.graph1()
.toJSON();
const sortedEdgeAddresses = sortedEdgeAddressesFromJSON(json);
const expected = sortedEdgeAddresses.slice().sort();
expect(sortedEdgeAddresses).toEqual(expected);
});
it("sortedNodeAddressesFromJSON", () => {
const json = advancedGraph()
.graph1()
.toJSON();
const sortedNodeAddresses = sortedNodeAddressesFromJSON(json);
const expected = sortedNodeAddresses.slice().sort();
expect(sortedNodeAddresses).toEqual(expected);
});
}); });