Add MutexMap MutexSection/RMutexSection#47
Add MutexMap MutexSection/RMutexSection#47PabloMK7 wants to merge 2 commits intoPretendoNetwork:masterfrom
Conversation
|
This change will also help refactoring PretendoNetwork/nex-protocols-common-go#28 |
|
Some of the naming here would also likely be confusing/misleading. Also the use of the name mm := NewMutexMap[int, string]()
mm.Atomic(func(mapInterface *MapInterface[int, string]) {
for i := 0; i < 10; i++ {
fmt.Println(mapInterface.Size())
if i == 5 {
return
}
mapInterface.Set(i, "test")
}
})This prints size changes for every iteration. If this were truly atomic I would assume that no changes to |
It's atomic in concurrent terms. All the operations inside the callback will be done without other threads interfering. I'm open to name suggestions such as |
To keep all the utility functions the same. That way if we find other places where this is needed we don't need to rewrite the logic too much. |
That's fair. I was thinking in terms of atomic operations typically seen in systems such as databases (but can be used outside of them) which take the form of "all-or-nothing" transactions. All operations either happen, or none do, with the results all applying at the same time if they do apply These kinds of atomic operations here would be linearizability, so maybe taking some language from here would clear up the specific type of atomic operations being done here? Or at the very least updating the Godoc comment to note which kind of atomicity is being used |
29c5acd to
4cb78b1
Compare
4cb78b1 to
9da218d
Compare
|
Please re-review. The changes will be useful in the future even if the original bug this aimed to fix was fixed in a different way. |
9da218d to
008e0d2
Compare
| // RawMap implements a map type with helper functions to operate it. | ||
| type RawMap[K comparable, V any] struct { | ||
| real map[K]V | ||
| } |
There was a problem hiding this comment.
This can just be made into a type alias rather than creating a whole struct
| // RawMap implements a map type with helper functions to operate it. | |
| type RawMap[K comparable, V any] struct { | |
| real map[K]V | |
| } | |
| // RawMap implements a map type with helper functions to operate it. | |
| type RawMap[K comparable, V any] map[K]V |
Then it can just be used like a regular map, how real is being used internally. Though I'm not sure what the benefit of this type is right now, since all it seems to do is wrap a map and then give it helper functions for things Go already supports?
Like why use RawMap.Delete() rather than just using a normal map and the built in delete()?
| // MutexMap implements a map type with go routine safe accessors through mutex locks. Embeds sync.RWMutex | ||
| type MutexMap[K comparable, V any] struct { | ||
| *sync.RWMutex | ||
| real map[K]V | ||
| mutex *sync.RWMutex | ||
| rawMap RawMap[K, V] | ||
| } |
There was a problem hiding this comment.
We prefer if structs are defined directly before their methods, so this should be moved further down
|
|
The previous implementation of the
MutexMapdidn't allow performing multiple operations (Get+DeleteorGet+Set) in a mutually exclusive way, as locking the map manually withLock()would cause a recursive lock when trying to call any of the methods. For that reason, I split theMutexMapintoMutexMapandMap. Both structs have the same methods, but only theMutexMapmethods actually lock the map. I also addedMutexSectionandRMutexSectionmethods toMutexMap, with runs a callback with aMap, that allows performing multiple operations to the map in an atomic way.