-
Notifications
You must be signed in to change notification settings - Fork 11
Description
Ptr and PtrList are useful constructs but they don't exactly match the usage patterns present in this library. I see two problems both relating to the fallible nature of acquiring locks the data:
- It makes the API more "noisy". I'm not sure that many of these functions even can fail to acquire a lock since they're almost exclusively reads. But we still hoist the potential for those errors into the API, requiring the user to handle them. Or there are some places where we simply unwrap a lock result. While I think that those unwraps are unlikely to error I hope it illustrates the point.
- It makes implementations more verbose as one has consider the guard lifetimes.
Neither of these are necessarily damning (well, the first more than the second, maybe) but my feeling that they are important is compounded by my perception that we aren't using the interior mutability aspect of aRwLock. All of the places that we acquire a write lock are behind a mutable reference already. It seems to me that we're exclusively using the reference counting aspect ofPtrandPtrListand not the interior mutability at all. As such, perhaps there is a more applicable abstraction.
I also have a sense that if things like the layer maps were modified from outside of the containing data structures there is significant potential for breakage. Or at least it's not clear to me that allowing changes to interior data apart from the API is desired.
Solutions
Replace std::sync::RwLock with parking_lot::RwLock
Pros: Low effort.
Cons: Doesn't really fix point 2 but would improve point 1.
Use a slotmap/petgraph
We're representing a directed graph. Petgraph is well used and loved for good reason. This would solve both problems and potentially allow us to leverage existing patterns for traversal and analysis.
Pros: The arena allows us to maintain cheap, potentially cyclical "references". Mutating only from behind a mutable reference creates patterns that users expect.
Cons: Access to the actual resource requires access to the arena. Functions like Layout::flatten would require a reference to the containing library, etc.
Replace Ptr with arc_swap::ArcSwap
Pros: We're mostly read-heavy so we get to keep our pointer semantics while getting ride of the locks & guards.
Cons: Our individual cells become copy-on-write by necessity.
There are probably other ways of doing this but I think these represent a good start.
My personal inclination would be towards a slotmap/petgraph but I think I would be easily convinced of ArcSwap as well.