You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I know that may be several other options for the semantics besides mentioned at https://github.com/google/guava/wiki/GraphsExplained#accessor-behavior, and that "generally using" one of them is not a strict guarantee of any kind, nevertheless behavior, that I've encountered today, surprised me a lot.
Accessor behavior
For accessors that return a collection, there are several options for the semantics, including:
(...)
2. Collection is an unmodifiable view (e.g. Collections.unmodifiableSet()): attempts to modify the collection in any way will throw an exception [emphasis added], and modifications to the graph will be reflected in the collection.
(...)
(...); as of this writing, the built-in implementations generally use (2).
My general impression was that ImmutableGraph.nodes(), ImmutableGraph.edges() and other views should behave as if they were Collections.unmodifiableSet(). This is not always true as I will show.
Two of the above are failing: emptyNodesAreUnmodifiable() and emptyEdgesAreUnmodifiable().
Nothing happens when clear() is being invoked on empty view. I believe this is indeed an attempt to modify the collection, so UnsupportedOperationException should be thrown.
If you would like to make some changes, please remember about remove* and retainAll methods.
Probably related discussion on even stronger guarantees: #3480
The text was updated successfully, but these errors were encountered:
Sometimes it depends if graph is directed or not, or what element order it uses. It seems that the problem results from the use of anonymous AbstractSets in most of views implementations. The most obvious (naive maybe?) solution would be to override all of the view-related accessors in ImmutableGraph and wrap sets returned by superclasses with Collections.unmodifiableSet().
The same problem likely applies to all (?) ImmutableValueGraph and ImmutableNetwork views, e.g. nodes().
Even for collections, this has always been a philosophical gray area. The general specification for remove, for example, is really "remove IF found". The general dictionary meanings of "immutable" and "unmodifiable" are about preventing actual change to the data.
java.util.Collection has this to say: "These methods may, but are not required to, throw an UnsupportedOperationException if the invocation would have no effect on the collection."
And re: graphs, the text that you boldfaced is perfectly accurate depending on whether one considers it an actual "attempt" to modify data or not.
With that said, I do think that the behavior you're asking for is slightly better. It's better to always fail on a "structurally" invalid request even though it "just happened to be harmless" in these particular circumstances. Not doing so can create a "time bomb" in the code.
kevinb9n
changed the title
ImmutableGraph views not unmodifiable enough
Graphs: immutable/unmodifiable operations should consistently throw UOE whether or not data would actually change
May 27, 2020
I know that may be several other options for the semantics besides mentioned at https://github.com/google/guava/wiki/GraphsExplained#accessor-behavior, and that "generally using" one of them is not a strict guarantee of any kind, nevertheless behavior, that I've encountered today, surprised me a lot.
My general impression was that
ImmutableGraph.nodes()
,ImmutableGraph.edges()
and other views should behave as if they wereCollections.unmodifiableSet()
. This is not always true as I will show.Two of the above are failing:
emptyNodesAreUnmodifiable()
andemptyEdgesAreUnmodifiable()
.Nothing happens when
clear()
is being invoked on empty view. I believe this is indeed an attempt to modify the collection, soUnsupportedOperationException
should be thrown.If you would like to make some changes, please remember about
remove*
andretainAll
methods.Probably related discussion on even stronger guarantees: #3480
The text was updated successfully, but these errors were encountered: