make GossipData immutable

The same piece of GossipData can be shared and subject to different
Merge operations. We either need to copy the data when we share it, or
create copies on modification, i.e. copy-on-write.

We choose the latter, since it is more efficient and there is just one
mutating operation.

Fixes #1697.
This commit is contained in:
Matthias Radestock committed 2015-11-17 20:13:46 +00:00
1 parent de802f9d76
commit 3cd199e852
6 files changed
+32 -21

No files matched your search

+10 -4
View File
@@ -245,12 +245,18 @@ type GossipData struct {
Entries
}
func (g *GossipData) Merge(o mesh.GossipData) {
func (g *GossipData) Merge(o mesh.GossipData) mesh.GossipData {
other := o.(*GossipData)
g.Entries.merge(other.Entries)
if g.Timestamp < other.Timestamp {
g.Timestamp = other.Timestamp
gossip := &GossipData{
Entries: make(Entries, len(g.Entries)),
Timestamp: g.Timestamp,
}
copy(gossip.Entries, g.Entries)
gossip.Entries.merge(other.Entries)
if gossip.Timestamp < other.Timestamp {
gossip.Timestamp = other.Timestamp
}
return gossip
}
func (g *GossipData) Decode(msg []byte) error {
+2 -2
View File
@@ -117,7 +117,7 @@ func TestGossipDataMerge(t *testing.T) {
g1 := GossipData{Entries: makeEntries("AcDf")}
g2 := GossipData{Entries: makeEntries("BEf")}
g1.Merge(&g2)
g3 := g1.Merge(&g2).(*GossipData)
require.Equal(t, GossipData{Entries: makeEntries("ABcDEf")}, g1)
require.Equal(t, GossipData{Entries: makeEntries("ABcDEf")}, *g3)
}