From 6dbfc218468d6aa13d0fa5543cbe1fb7d41f3d68 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Tue, 3 Nov 2015 18:54:59 -0800 Subject: [PATCH 1/2] storage: delete key instead of setting it to false When getting the watched events, it iterate all keys in putm and delm to generate the events. If we don't delete the key from putm/delm, it would range on the key that is not actually put or deleted. This is incorrect. Fix the panic that happens when single put/delete is watched. --- storage/watchable_store.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/storage/watchable_store.go b/storage/watchable_store.go index 02c790f05..12db37b0a 100644 --- a/storage/watchable_store.go +++ b/storage/watchable_store.go @@ -317,12 +317,16 @@ func newOngoingTx() *ongoingTx { func (tx *ongoingTx) put(k string) { tx.putm[k] = true - tx.delm[k] = false + if _, ok := tx.delm[k]; ok { + delete(tx.delm, k) + } } func (tx *ongoingTx) del(k string) { tx.delm[k] = true - tx.putm[k] = false + if _, ok := tx.putm[k]; ok { + delete(tx.putm, k) + } } type watching struct { From c8e622f5174872d645555e02a66bfdd760890af6 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Tue, 3 Nov 2015 19:10:45 -0800 Subject: [PATCH 2/2] storage: make putm/delm a set with empty value This cleans the code, and reduces the allocation space. --- storage/watchable_store.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/storage/watchable_store.go b/storage/watchable_store.go index 12db37b0a..e841532e0 100644 --- a/storage/watchable_store.go +++ b/storage/watchable_store.go @@ -304,26 +304,26 @@ func (s *watchableStore) notify(rev int64, ev storagepb.Event) { type ongoingTx struct { // keys put/deleted in the ongoing txn - putm map[string]bool - delm map[string]bool + putm map[string]struct{} + delm map[string]struct{} } func newOngoingTx() *ongoingTx { return &ongoingTx{ - putm: make(map[string]bool), - delm: make(map[string]bool), + putm: make(map[string]struct{}), + delm: make(map[string]struct{}), } } func (tx *ongoingTx) put(k string) { - tx.putm[k] = true + tx.putm[k] = struct{}{} if _, ok := tx.delm[k]; ok { delete(tx.delm, k) } } func (tx *ongoingTx) del(k string) { - tx.delm[k] = true + tx.delm[k] = struct{}{} if _, ok := tx.putm[k]; ok { delete(tx.putm, k) }