diff --git a/packages/datastructure/krw_mutex.go b/packages/datastructure/krw_mutex.go new file mode 100644 index 0000000000000000000000000000000000000000..2b05ce371275955fba2fdbb161f35ff58b37d107 --- /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 0000000000000000000000000000000000000000..bb5290aba7c4be3151e082edb4071611e4f664af --- /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 6548346b1f3db226545bfb47900e559d9066b1f5..82a3b8fde8ac9a4053dc7c01f42f434d85a69524 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") }