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

c-ffi,go-lockbook: better support for uuids #8

Merged
merged 5 commits into from
Jan 22, 2023

Conversation

steverusso
Copy link
Owner

@steverusso steverusso commented Jan 21, 2023

Currently in the "C interface" as well call it, file IDs (which are v4 UUIDs) are passed over FFI as C strings (both ways), and they're stored as strings in Go. There are two major changes in this PR:

  1. UUIDs will be passed over FFI both ways as 16 byte array values.
  2. UUIDs in Go will be a more powerful UUID type instead of a plain string.

Memory Efficiency Throughout

Memory usage for a UUID as a string in Go is 52 bytes:

  • the string header is 16 (the pointer and length are each 8)
  • the actual hex representation (aka. the length of the string's content) is 36

That's not to mention the overhead of heap allocating and freeing a C string to pass over FFI each way.

Ergonomics, Particularly in Go

For developers consuming the C API as is, it'd be better to have one less heap allocated value to think about, especially when the value in question (a UUID) has a small and known size. But for Go developers, it'd be cool to use a UUID library such as gofrs/uuid instead of plain old strings.


Improvements & Summary

UUID values are stack allocated and copied both ways over FFI. They're stored as a uuid.UUID in Go (which is essentially a [16]byte). No heap allocations either way, and the C values in Go aren't even managed by the GC.

Side note: C only passes arrays by pointer, and cbindgen has adjusted for this and will warn you if you try it. Therefore, I had to use the "trick" of wrapping the 16 byte array in a struct. While this is considered bad practice by some, I decided that it'll be fine in this case, which is anytime a standalone UUID needs to be passed over FFI. It looks like:

pub const UUID_LEN: usize = 16;

#[repr(C)]
pub struct LbFileId {
    data: [u8; UUID_LEN],
}

Closes #6.

this already means that the entire LbFileType struct is stack allocated,
and thus no longer needs a free function.
@steverusso steverusso self-assigned this Jan 21, 2023
@steverusso steverusso marked this pull request as draft January 21, 2023 00:38
@steverusso steverusso marked this pull request as ready for review January 22, 2023 00:35
@steverusso steverusso merged commit 8c1270e into master Jan 22, 2023
@steverusso steverusso deleted the better-uuid-support branch January 22, 2023 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

richer uuid support in go bindings
1 participant