Expose the Graph's modification count (#1055)

This commit adds a new `modificationCount` method to `Graph`, which
exposes's that graph's modification count. This enables clients to write
cached data structures on top of Graph, knowing that they can
programatically detect when the cache has been invalidated.

Test plan: Unit tests have been addded; `yarn test` passes.

This commit is motivated by work on #1020.
This commit is contained in:
Dandelion Mané 2019-01-21 10:08:27 -08:00 committed by GitHub
parent e92f247305
commit 5c2f232017
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 1 deletions

View File

@ -148,7 +148,7 @@ export opaque type GraphJSON = Compatible<{|
+edges: IndexedEdgeJSON[],
|}>;
type ModificationCount = number;
export type ModificationCount = number;
export class Graph {
_nodes: Set<NodeAddressT>;
@ -204,6 +204,26 @@ export class Graph {
this._maybeCheckInvariants();
}
/**
* Returns how many times the graph has been modified.
*
* This value is exposed so that users of Graph can cache computations over
* the graph with confidence, knowing that they will be able to check the
* modification count to know when their cache is potentially invalid.
*
* This value may increase any time the graph is potentially modified, even
* if no modification actually occurs; for example, if a client calls
* `addNode`, the modification count may increase even if the added node was
* already present in the graph.
*
* This value is not serialized, and is ignored when checking equality, i.e.
* two graphs may be semantically equal even when they have different
* modification counts.
*/
modificationCount(): ModificationCount {
return this._modificationCount;
}
/**
* Adds a new node to the graph.
*

View File

@ -74,6 +74,29 @@ describe("core/graph", () => {
}).toThrow("modification count in the future");
});
describe("modification count retrieval", () => {
it("modification count starts at 0", () => {
const g = new Graph();
expect(g.modificationCount()).toEqual(0);
});
it("modification count increases after any potential modification", () => {
const g = new Graph();
expect(g.modificationCount()).toEqual(0);
g.addNode(NodeAddress.empty);
expect(g.modificationCount()).toEqual(1);
g.addNode(NodeAddress.empty);
expect(g.modificationCount()).toEqual(2);
});
it("graphs can be equal despite unequal modification count", () => {
const g1 = new Graph()
.addNode(NodeAddress.empty)
.removeNode(NodeAddress.empty);
const g2 = new Graph();
expect(g1.equals(g2)).toEqual(true);
expect(g1.modificationCount()).not.toEqual(g2.modificationCount());
});
});
describe("automated invariant checking", () => {
const src = NodeAddress.fromParts(["src"]);
const dst = NodeAddress.fromParts(["dst"]);