113 lines
2.9 KiB
Go
113 lines
2.9 KiB
Go
|
/*
|
||
|
A simple wrapper around an in memory key value store, allows to change the implementation if needed.
|
||
|
The version using sync.Map produces strange results in the tests so we left it unused for now.
|
||
|
*/
|
||
|
package kademlia
|
||
|
|
||
|
import (
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type storageItem struct {
|
||
|
Value []byte
|
||
|
TTL uint16
|
||
|
RepCount uint16
|
||
|
timeAdded time.Time
|
||
|
}
|
||
|
|
||
|
type KeyType [32]byte
|
||
|
type ValueType storageItem
|
||
|
|
||
|
type DHTStorage struct {
|
||
|
//storageMap sync.Map
|
||
|
storageMap map[[32]byte]ValueType
|
||
|
}
|
||
|
|
||
|
func (m *DHTStorage) GetEntry(key [32]byte) (ValueType, bool) {
|
||
|
/*val, exists := m.storageMap.Load(key)
|
||
|
val2, _ := val.(ValueType)*/
|
||
|
val2, exists := m.storageMap[key]
|
||
|
return val2, exists
|
||
|
}
|
||
|
|
||
|
// GetValue
|
||
|
/*
|
||
|
Returns only the value of an entry associated with the provided key, if it exists.
|
||
|
*/
|
||
|
func (m *DHTStorage) GetValue(key [32]byte) ([]byte, bool) {
|
||
|
/*val, exists := m.storageMap.Load(key)
|
||
|
val2, _ := val.(ValueType) */
|
||
|
val2, exists := m.storageMap[key]
|
||
|
return val2.Value, exists
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Put places an entry with the fields provided and records the time it got added.
|
||
|
*/
|
||
|
func (m *DHTStorage) Put(key [32]byte, value []byte, ttl uint16, repCount uint16) {
|
||
|
/*m.storageMap.Store(key, ValueType(storageItem{
|
||
|
Value: value,
|
||
|
TTL: ttl,
|
||
|
RepCount: repCount,
|
||
|
timeAdded: time.Now(),
|
||
|
}))*/
|
||
|
|
||
|
m.storageMap[key] = ValueType(storageItem{
|
||
|
Value: value,
|
||
|
TTL: ttl,
|
||
|
RepCount: repCount,
|
||
|
timeAdded: time.Now(),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func (m *DHTStorage) UpdateAndExpireEntries(elapsedTime time.Duration) {
|
||
|
// Iterating over a sync.Map is a bit ugly, but this is the same as including the method body in a for range loop
|
||
|
/*m.storageMap.Range(func(k, e any) bool {
|
||
|
key := k.([32]byte)
|
||
|
entry := e.(ValueType)
|
||
|
// If the entry expired: delete
|
||
|
if (time.Duration(entry.TTL)*time.Second)-elapsedTime <= time.Second {
|
||
|
m.storageMap.Delete(key)
|
||
|
} else {
|
||
|
//Otherwise: update the TTL field for the remaining time
|
||
|
entry.TTL = entry.TTL - uint16(elapsedTime/time.Second)
|
||
|
m.storageMap.Store(key, entry)
|
||
|
}
|
||
|
return true
|
||
|
}) */
|
||
|
|
||
|
for key, entry := range m.storageMap {
|
||
|
|
||
|
// If the entry expired: delete
|
||
|
if (time.Duration(entry.TTL)*time.Second)-elapsedTime <= 0 {
|
||
|
delete(m.storageMap, key)
|
||
|
} else {
|
||
|
//Otherwise: update the TTL field for the remaining time
|
||
|
entry.TTL = entry.TTL - uint16(elapsedTime/time.Second)
|
||
|
m.storageMap[key] = entry
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (m *DHTStorage) GetEntriesForRepublishing(timeLimit time.Duration) map[KeyType]ValueType {
|
||
|
var toBeRepublished = map[KeyType]ValueType{}
|
||
|
|
||
|
/*m.storageMap.Range(func(k, e any) bool {
|
||
|
key := k.([32]byte)
|
||
|
entry := e.(ValueType)
|
||
|
if time.Now().Sub(entry.timeAdded) >= timeLimit {
|
||
|
toBeRepublished[key] = entry
|
||
|
m.storageMap.Delete(key)
|
||
|
}
|
||
|
return true
|
||
|
})*/
|
||
|
|
||
|
for key, entry := range m.storageMap {
|
||
|
if time.Now().Sub(entry.timeAdded) >= timeLimit {
|
||
|
toBeRepublished[key] = entry
|
||
|
delete(m.storageMap, key)
|
||
|
}
|
||
|
}
|
||
|
return toBeRepublished
|
||
|
}
|