Sharing is a form of Copy-On-Write (COW) optimization with Reference Counting.
Containers like List and String use sharing:
- This works in conjunction with Slicing to improve performance by minimizing memory reallocation and copying
- When a container is copied, a "shared" copy may be used, meaning the underlying data is shared between two (or more) objects
- Some containers (such as String) may also share a raw pointer (read-only data) such as a string literal – see example below
- Never assign (or copy construct from) a raw pointer to an Evo container unless it refers to static immutable data (ex: string literal), otherwise use copy() method or a dumb pointer (Ptr)
- Copying from a managed pointer (SmartPtr, Ptr, etc) always makes a full (unshared) copy
- A shared copy will become a full copy when a write operation (modifier) is called
- An empty container is considered unshared (no data is shared)
- Containers that support sharing will have these methods:
- Constructors: Same as
set(src)
set(src)
– Set as copy (shared copy if possible)
copy(src)
– Set as full (unshared) copy
operator=(src)
– Same as set(src)
shared()
– Get whether shared
unshare()
– If shared then make unshared, allocating a new buffer if needed – calls unslice() (if present)
- Some containers only reference (i.e. don't own) data (ex: SubString), for these
unshare()
is a no-op and shared()
always returns false
- Modifier methods end with an uppercase 'M' to distinguish them, these effectively call
unshare()
to make the internal buffer unshared and writable
- Sharing is automatic, though being mindful of how "modifier" methods are used will improve performance
- Caution: Sharing can impact thread safety, always make full (unshared) copies across separate threads
Containers that support Sharing: List, String, PtrList, MapList, MapHash
- Example
int main() {
str << " 123";
str.
split(
' ', left, right);
left << "ing";
c.
out << left <<
',' << right <<
NL;
return 0;
}
- Example with raw pointer
int main() {
char buf[10];
strcpy(buf, "testing");
str = "foo";
str = buf;
return 0;
}
- Example with sharing and slicing
int main() {
str.slice(1, 4);
str << "- 123";
str.
split(
'-', left, right);
left << "ing";
c.
out << left <<
',' << right <<
NL;
}