Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for immutable handles in genvector #17

Open
cher-nov opened this issue Apr 22, 2020 · 0 comments
Open

Support for immutable handles in genvector #17

cher-nov opened this issue Apr 22, 2020 · 0 comments
Assignees

Comments

@cher-nov
Copy link
Owner

cher-nov commented Apr 22, 2020

The main disadvantage of vector implementation with C-like access (that is, vec[i] instead of smth like vec_value( vec, i ) or vec->data[i]) is that we have to modify all the references on any vector operation that reallocates the underlying buffer. That could be not suitable for some cases.

There's a concept. To keep all the things unified, we can just add a data field into the vector header that will be NULL if vector is in the "mutable handles" mode (as now), and point to the data buffer otherwise.

Problems:

  1. A set of functions obtaining the immutable handle type to operate on a vector will be reqired in a naive case, which is sucks (especially due to the nature of function instantiation). But it can be overcomed using the "reduced header" trick. That is, the data field in the header should be the last one. Thus, on every IGVEC_HEADER() we must go sizeof(void*) bytes back and examine the value. It it's NULL, then we're in the mutable mode so the header is up there. Otherwise, the examined value points to the header stored separately (which is the immutable handle), while the data field of the header itself points to the first element of the data (but not the actual buffer - its location is data - sizeof(void*)!). Thereby, we can operate on vectors using immutable handles just by passing immutable_handle->data (or &(immutable_handle->data) when required) to the same functions as used by regular mutable vectors, which is pretty cool.
    By using another sizeof(void*) bytes of overhead we can go deeper and implement immutable headers that we'll can pass to functions just as mutable ones, i.e. without the ->data part. "Immutability costs", lol. But this is dirty from the point of view of types (it's better to have "immutable handle" as type alias of the type of header) and readability (easiness to mess up the mutable and the immutable handles). And how to access the actual vector data (particularly, its elements) in that case? However, in case of vec->data we can't access elements too because it's void*.
    I should think of both implementations more thoroughly. Maybe it's better to have two different vector implementations at all (mutable / immutable)? But this is code duplication, and it sucks. But does anyone really need the mode switching feature?
    Oh, a real trilemma of "speed / space / code beauty". :(

  2. On separating header from data and merging it back there we must note that realloc() doesn't guarantee in-place modification even if the size is less that it was:
    https://stackoverflow.com/questions/3162502/is-realloc-guaranteed-to-be-in-place-when-the-buffer-is-shrinking

All of this is closely related to #7.

@cher-nov cher-nov self-assigned this Apr 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant