From 754ace9023f852910fd8e07bddea8500d7b4b76b Mon Sep 17 00:00:00 2001 From: Hans Moog <hm@mkjc.net> Date: Fri, 5 Jul 2019 17:13:51 +0200 Subject: [PATCH] Feat: added a KRWMutex which allows locking per unique id --- packages/datastructure/krw_mutex.go | 53 ++++++++++++++++++++++++ packages/datastructure/krw_mutex_test.go | 23 ++++++++++ plugins/tangle/transaction_metadata.go | 3 -- 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 packages/datastructure/krw_mutex.go create mode 100644 packages/datastructure/krw_mutex_test.go diff --git a/packages/datastructure/krw_mutex.go b/packages/datastructure/krw_mutex.go new file mode 100644 index 00000000..2b05ce37 --- /dev/null +++ b/packages/datastructure/krw_mutex.go @@ -0,0 +1,53 @@ +package datastructure + +import ( + "sync" +) + +type KRWMutex struct { + keyMutexConsumers map[interface{}]int + keyMutexes map[interface{}]*sync.RWMutex + mutex sync.RWMutex +} + +func NewKRWMutex() *KRWMutex { + return &KRWMutex{ + keyMutexConsumers: make(map[interface{}]int), + keyMutexes: make(map[interface{}]*sync.RWMutex), + } +} + +func (krwMutex *KRWMutex) Register(key interface{}) (result *sync.RWMutex) { + krwMutex.mutex.Lock() + + if val, exists := krwMutex.keyMutexConsumers[key]; exists { + krwMutex.keyMutexConsumers[key] = val + 1 + result = krwMutex.keyMutexes[key] + } else { + result = &sync.RWMutex{} + + krwMutex.keyMutexConsumers[key] = 1 + krwMutex.keyMutexes[key] = result + } + + krwMutex.mutex.Unlock() + + return +} + +func (kwrMutex *KRWMutex) Free(key interface{}) { + kwrMutex.mutex.Lock() + + if val, exists := kwrMutex.keyMutexConsumers[key]; exists { + if val == 1 { + delete(kwrMutex.keyMutexConsumers, key) + delete(kwrMutex.keyMutexes, key) + } else { + kwrMutex.keyMutexConsumers[key] = val - 1 + } + } else { + panic("trying to free non-existent key") + } + + kwrMutex.mutex.Unlock() +} diff --git a/packages/datastructure/krw_mutex_test.go b/packages/datastructure/krw_mutex_test.go new file mode 100644 index 00000000..bb5290ab --- /dev/null +++ b/packages/datastructure/krw_mutex_test.go @@ -0,0 +1,23 @@ +package datastructure + +import ( + "testing" +) + +func TestKRWMutex_Free(t *testing.T) { + krwMutex := NewKRWMutex() + + krwMutex.Register("test") + krwMutex.Register("test") + krwMutex.Free("test") + krwMutex.Free("test") +} + +func BenchmarkKRWMutex(b *testing.B) { + krwMutex := NewKRWMutex() + + for i := 0; i < b.N; i++ { + krwMutex.Register(i) + krwMutex.Free(i) + } +} diff --git a/plugins/tangle/transaction_metadata.go b/plugins/tangle/transaction_metadata.go index 6548346b..82a3b8fd 100644 --- a/plugins/tangle/transaction_metadata.go +++ b/plugins/tangle/transaction_metadata.go @@ -90,9 +90,6 @@ func storeTransactionMetadataInDatabase(metadata *transactionmetadata.Transactio if marshaledMetadata, err := metadata.Marshal(); err != nil { return err } else { - if len(marshaledMetadata) != 97 { - panic("WATT") - } if err := transactionMetadataDatabase.Set(metadata.GetHash().CastToBytes(), marshaledMetadata); err != nil { return ErrDatabaseError.Derive(err, "failed to store transaction metadata") } -- GitLab