并发重读工作负载的数据结构

问题描述 投票:0回答:1

我正在寻找一个存储32字节字符串的数据结构,并允许快速查找具有首选O(1)或O(log N)查找复杂性(目标只是确定密钥是否存在)。移除和插入复杂性并不重要,因为这些操作很少。

并不是说它与问题有关,而是我在Go工作。我可以使用由互斥锁支持的hashmap,但争用将是一个问题,如果有更好的解决方案,我更愿意避免分片。

谢谢

algorithm go data-structures containers
1个回答
0
投票

map对于并发读取是安全的。您可以将所需的地图放在sync/atomic.Value中,当您想要写入时,复制地图并更改它,然后将其放回Value内。来自docs

以下示例说明如何使用写时复制习惯维护可扩展的频繁读取但不经常更新的数据结构。

码:

type Map map[string]string
var m Value
m.Store(make(Map))
var mu sync.Mutex // used only by writers
// read function can be used to read the data without further synchronization
read := func(key string) (val string) {
        m1 := m.Load().(Map)
        return m1[key]
}
// insert function can be used to update the data without further synchronization
insert := func(key, val string) {
        mu.Lock() // synchronize with other potential writers
        defer mu.Unlock()
        m1 := m.Load().(Map) // load current value of the data structure
        m2 := make(Map)      // create a new value
        for k, v := range m1 {
                m2[k] = v // copy all data from the current object to the new one
        }
        m2[key] = val // do the update that we need
        m.Store(m2)   // atomically replace the current object with the new one
        // At this point all new readers start working with the new version.
        // The old version will be garbage collected once the existing readers
        // (if any) are done with it.
}
_, _ = read, insert

您也可以使用指向map而不是Value的指针,并使用StorePointer/LoadPointer以原子方式存储它,但这不是更清晰,因为您应该使用不安全的指针并投射它。

© www.soinside.com 2019 - 2024. All rights reserved.