Skip to content

CDRIVER-5641: BSON Binary Vector Subtype Support #1868

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

Merged
54 commits merged into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
2b0af51
Sync bson_corpus spec tests
Feb 14, 2025
c22ad4e
Sync bson binary vector spec tests
Feb 13, 2025
9287971
New documentation pages
Feb 14, 2025
b01c769
New source files for the implementation of BSON Binary Vector
Feb 14, 2025
c1ab6e9
Changes to integrate bson-binary-vector with libbson
Feb 6, 2025
6fe0d0a
Note about the differing public and private API of bson_iter_binary a…
Feb 18, 2025
9263e89
Public APIs for direct pointer access to int8 vectors
Feb 18, 2025
ae91e0d
Trivial, fix inline placement
Feb 18, 2025
75a0984
Trivial, avoid temporarily viewing header bytes as int8_t
Feb 18, 2025
6168cb2
Fix typo in man_page definition
Feb 18, 2025
1a68f6a
Update src/libbson/src/bson/bson.c
Feb 25, 2025
6270bc5
Update src/libbson/src/bson/bson.c
Feb 25, 2025
21c5054
Update src/libbson/src/bson/bson.c
Feb 25, 2025
edc9b20
Update src/libbson/src/bson/bson.c
Feb 25, 2025
fe491be
Update src/libbson/src/bson/bson-vector.c
Feb 25, 2025
217562c
Update src/libbson/src/bson/bson-vector-private.h
Feb 25, 2025
f6b58c0
Update src/libbson/src/bson/bson-vector.h
Feb 25, 2025
3fa7c05
Update src/libbson/src/bson/bson-vector.h
Feb 25, 2025
12e6edf
Update src/libbson/tests/test-bson-vector.c
Feb 25, 2025
41a7ebb
Update src/libbson/tests/test-bson-vector.c
Feb 25, 2025
149d441
Update src/libbson/tests/test-bson-vector.c
Feb 25, 2025
4b2d6f3
Rename packed_bits to packed_bit
Feb 26, 2025
fb3967c
Merge branch 'master' into CDRIVER-5641
Feb 26, 2025
a17e716
Represent array keys with uint32_t not size_t
Feb 26, 2025
f3527ec
In public headers, disable pointer arithmetic warnings from -Weverything
Feb 27, 2025
dc9d22f
Style change, prefer to write element address calculation as plain ad…
Feb 27, 2025
150d9c2
Add _uninit suffix to allocators for uninitialized vectors
Feb 27, 2025
758856a
Use INFINITY and NAN for float but not double
Feb 27, 2025
e93b66c
Note about low RAND_MAX on windows
Feb 27, 2025
aea2bef
Adjust type for fuzzer random inputs
Feb 27, 2025
6f732fc
libbson bugfix, allow allocating max size documents
Feb 27, 2025
3969826
Edge case tests for sizing, allocation, and accessors
Feb 27, 2025
57a2a0d
Move read/write edge case tests to macros
Feb 27, 2025
05bd56a
bugfix for test_bson_reserve_buffer_errors
Feb 27, 2025
abbe3cc
Merge branch 'master' into CDRIVER-5641
Feb 27, 2025
d1b35d0
Revert "libbson bugfix, allow allocating max size documents"
Feb 27, 2025
91adb2a
Revert "bugfix for test_bson_reserve_buffer_errors"
Feb 27, 2025
f2bb318
CDRIVER-5915: Fix for allocation of bson_t larger than half max size
Feb 27, 2025
c1363b0
Revert "Use INFINITY and NAN for float but not double"
Feb 27, 2025
277dda0
clang-format
Feb 27, 2025
f8a3497
Explicitly cast INFINITY to double
Feb 27, 2025
fc7772d
Fix missing underline from earlier _uninit change
Feb 27, 2025
3e4ec4b
test-bson-vector read/write edge cases use malloc'ed value buffers
Feb 27, 2025
35b0b31
Reconsider function name (_bson_round_up_alloc_size)
Feb 27, 2025
7b2c324
Update src/libbson/tests/test-bson-vector.c
Feb 28, 2025
4337a3d
Update src/libbson/tests/test-bson-vector.c
Feb 28, 2025
f89c255
End statement-like macros with a statement that requires a semicolon
Feb 28, 2025
66104f7
Replace BSON_ASSERT with ASSERT in test-bson-vector
Feb 28, 2025
36f544d
Explicit casts for all rand() calls in test-bson-vector
Feb 28, 2025
ca5171d
Improve ASSERT_MEMCMP somewhat
Mar 1, 2025
1702a2a
Use ASSERT_MEMCMP for exact comparison of float32 and other bulk elem…
Mar 1, 2025
3e3d4db
Revert "Reconsider function name (_bson_round_up_alloc_size)"
Mar 3, 2025
bcb2b87
Revert "CDRIVER-5915: Fix for allocation of bson_t larger than half m…
Mar 3, 2025
8e41a4c
Merge branch 'master' into CDRIVER-5641
Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/libbson/doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ API Reference
bson_writer_t
bson_get_monotonic_time
bson_memory
binary_vector
version
legacy_extended_json
149 changes: 149 additions & 0 deletions src/libbson/doc/binary_vector.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
:man_page: libbson_binary_vector

BSON Binary Vector subtype
==========================

In Libbson, we use the term *Vector* to refer to a data representation for compact storage of uniform elements, defined by the `BSON Binary Subtype 9 - Vector <https://github.com/mongodb/specifications/blob/master/source/bson-binary-vector/bson-binary-vector.md>`_ specification.

Libbson includes API support for Vectors:

* The *view* APIs provide an efficient way to access elements of Vector fields that reside within :symbol:`bson_t` storage.
* Integration between *views* and other Libbson features: append, array builder, iter.
* Vectors can be converted to and from a plain BSON Array, subject to the specification's type conversion rules.

The specification currently defines three element types, which Libbson interprets as:

* ``int8``: signed integer elements, equivalent to C ``int8_t``.
* ``float32``: IEEE 754 floating point, 32 bits per element, least-significant byte first. After alignment and byte swapping, elements are equivalent to C ``float``.
* ``packed_bit``: single-bit integer elements, packed most-significant bit first. Accessible in packed form as C ``uint8_t`` or as unpacked elements using C ``bool``.

Vector Views
------------

.. toctree::
:titlesonly:
:maxdepth: 1

bson_vector_int8_view_t
bson_vector_int8_const_view_t
bson_vector_float32_view_t
bson_vector_float32_const_view_t
bson_vector_packed_bit_view_t
bson_vector_packed_bit_const_view_t

Integration
-----------

* Allocating Vectors inside :symbol:`bson_t`:

.. toctree::
:titlesonly:
:maxdepth: 1

bson_append_vector_int8_uninit
bson_append_vector_float32_uninit
bson_append_vector_packed_bit_uninit

* Accessing an existing Vector via :symbol:`bson_iter_t`:

.. code-block:: c

#define BSON_ITER_HOLDS_VECTOR(iter) /* ... */
#define BSON_ITER_HOLDS_VECTOR_INT8(iter) /* ... */
#define BSON_ITER_HOLDS_VECTOR_FLOAT32(iter) /* ... */
#define BSON_ITER_HOLDS_VECTOR_PACKED_BIT(iter) /* ... */

.. toctree::
:titlesonly:
:maxdepth: 1

bson_vector_int8_view_from_iter
bson_vector_int8_const_view_from_iter
bson_vector_float32_view_from_iter
bson_vector_float32_const_view_from_iter
bson_vector_packed_bit_view_from_iter
bson_vector_packed_bit_const_view_from_iter

Array Conversion
----------------

* Polymorphic array-from-vector:

.. toctree::
:titlesonly:
:maxdepth: 1

bson_append_array_from_vector

* Type specific array-from-vector:

.. toctree::
:titlesonly:
:maxdepth: 1

bson_append_array_from_vector_int8
bson_append_array_from_vector_float32
bson_append_array_from_vector_packed_bit

* Using :symbol:`bson_array_builder_t` for array-from-vector:

.. toctree::
:titlesonly:
:maxdepth: 1

bson_array_builder_append_vector_int8_elements
bson_array_builder_append_vector_float32_elements
bson_array_builder_append_vector_packed_bit_elements
bson_array_builder_append_vector_elements

* Type specific vector-from-array:

.. toctree::
:titlesonly:
:maxdepth: 1

bson_append_vector_int8_from_array
bson_append_vector_float32_from_array
bson_append_vector_packed_bit_from_array

Additional Definitions
----------------------

* Binary subtype:

.. code-block:: c

typedef enum {
BSON_SUBTYPE_VECTOR = 0x09,
/* ... */
} bson_subtype_t;

* Byte length of the Vector header:

.. code-block:: c

// Length of the required header for BSON_SUBTYPE_VECTOR, in bytes
#define BSON_VECTOR_HEADER_LEN 2

* Byte length for a Vector with specific element type and count:

.. toctree::
:titlesonly:
:maxdepth: 1

bson_vector_int8_binary_data_length
bson_vector_float32_binary_data_length
bson_vector_packed_bit_binary_data_length

* Errors:

.. code-block:: c

// Error "domain"
#define BSON_ERROR_VECTOR 4

.. toctree::
:titlesonly:
:maxdepth: 1

bson_vector_error_code_t
40 changes: 40 additions & 0 deletions src/libbson/doc/bson_append_array_from_vector.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
:man_page: bson_append_array_from_vector

bson_append_array_from_vector()
===============================

Synopsis
--------

.. code-block:: c

#define BSON_APPEND_ARRAY_FROM_VECTOR(b, key, iter) \
bson_append_array_from_vector (b, key, (int) strlen (key), iter)

bool
bson_append_array_from_vector (bson_t *bson,
const char *key,
int key_length,
const bson_iter_t *iter);

Parameters
----------

* ``bson``: A :symbol:`bson_t`.
* ``key``: An ASCII C string containing the name of the field.
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
* ``iter``: A :symbol:`bson_iter_t` pointing to any supported :doc:`binary_vector` field.

Description
-----------

Converts the Vector pointed to by ``iter`` into a plain BSON Array, written to ``bson`` under the name ``key``.

Returns
-------

Returns ``true`` if the operation was applied successfully. The function fails if appending the array grows ``bson`` larger than INT32_MAX, or if ``iter`` doesn't point to a valid recognized Vector type.

.. seealso::

| :symbol:`bson_array_builder_append_vector_elements`
40 changes: 40 additions & 0 deletions src/libbson/doc/bson_append_array_from_vector_float32.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
:man_page: bson_append_array_from_vector_float32

bson_append_array_from_vector_float32()
=======================================

Synopsis
--------

.. code-block:: c

#define BSON_APPEND_ARRAY_FROM_VECTOR_FLOAT32(b, key, view) \
bson_append_array_from_vector_float32 (b, key, (int) strlen (key), view)

bool
bson_append_array_from_vector_float32 (bson_t *bson,
const char *key,
int key_length,
bson_vector_float32_const_view_t view);

Parameters
----------

* ``bson``: A :symbol:`bson_t`.
* ``key``: An ASCII C string containing the name of the field.
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
* ``view``: A :symbol:`bson_vector_float32_const_view_t` pointing to validated ``float32`` :doc:`binary_vector` data.

Description
-----------

Converts the Vector pointed to by ``view`` into a plain BSON Array, written to ``bson`` under the name ``key``.

Returns
-------

Returns ``true`` if the operation was applied successfully. The function fails if appending the array grows ``bson`` larger than INT32_MAX.

.. seealso::

| :symbol:`bson_array_builder_append_vector_float32_elements`
40 changes: 40 additions & 0 deletions src/libbson/doc/bson_append_array_from_vector_int8.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
:man_page: bson_append_array_from_vector_int8

bson_append_array_from_vector_int8()
====================================

Synopsis
--------

.. code-block:: c

#define BSON_APPEND_ARRAY_FROM_VECTOR_INT8(b, key, view) \
bson_append_array_from_vector_int8 (b, key, (int) strlen (key), view)

bool
bson_append_array_from_vector_int8 (bson_t *bson,
const char *key,
int key_length,
bson_vector_int8_const_view_t view);

Parameters
----------

* ``bson``: A :symbol:`bson_t`.
* ``key``: An ASCII C string containing the name of the field.
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
* ``view``: A :symbol:`bson_vector_int8_const_view_t` pointing to validated ``int8`` :doc:`binary_vector` data.

Description
-----------

Converts the Vector pointed to by ``view`` into a plain BSON Array, written to ``bson`` under the name ``key``.

Returns
-------

Returns ``true`` if the operation was applied successfully. The function fails if appending the array grows ``bson`` larger than INT32_MAX.

.. seealso::

| :symbol:`bson_array_builder_append_vector_int8_elements`
40 changes: 40 additions & 0 deletions src/libbson/doc/bson_append_array_from_vector_packed_bit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
:man_page: bson_append_array_from_vector_packed_bit

bson_append_array_from_vector_packed_bit()
==========================================

Synopsis
--------

.. code-block:: c

#define BSON_APPEND_ARRAY_FROM_VECTOR_PACKED_BIT(b, key, view) \
bson_append_array_from_vector_packed_bit (b, key, (int) strlen (key), view)

bool
bson_append_array_from_vector_packed_bit (bson_t *bson,
const char *key,
int key_length,
bson_vector_packed_bit_const_view_t view);

Parameters
----------

* ``bson``: A :symbol:`bson_t`.
* ``key``: An ASCII C string containing the name of the field.
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
* ``view``: A :symbol:`bson_vector_packed_bit_const_view_t` pointing to validated ``packed_bit`` :doc:`binary_vector` data.

Description
-----------

Converts the Vector pointed to by ``view`` into a plain BSON Array, written to ``bson`` under the name ``key``.

Returns
-------

Returns ``true`` if the operation was applied successfully. The function fails if appending the array grows ``bson`` larger than INT32_MAX.

.. seealso::

| :symbol:`bson_array_builder_append_vector_packed_bit_elements`
4 changes: 4 additions & 0 deletions src/libbson/doc/bson_append_binary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ Returns
-------

Returns ``true`` if the operation was applied successfully. The function will fail if appending ``binary`` grows ``bson`` larger than INT32_MAX.

.. seealso::

| :symbol:`bson_append_binary_uninit`
43 changes: 43 additions & 0 deletions src/libbson/doc/bson_append_binary_uninit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
:man_page: bson_append_binary_uninit

bson_append_binary_uninit()
===========================

Synopsis
--------

.. code-block:: c

#define BSON_APPEND_BINARY_UNINIT(b, key, subtype, val, len) \
bson_append_binary_uninit (b, key, (int) strlen (key), subtype, val, len)

bool
bson_append_binary_uninit (bson_t *bson,
const char *key,
int key_length,
bson_subtype_t subtype,
uint8_t **binary,
uint32_t length);

Parameters
----------

* ``bson``: A :symbol:`bson_t`.
* ``key``: The key name.
* ``key_length``: The length of ``key`` in bytes or -1 to use strlen().
* ``subtype``: A bson_subtype_t indicating the binary subtype.
* ``binary``: Location for a pointer that will receive a writable pointer to the uninitialized binary data block.
* ``length``: The length of ``buffer`` in bytes.

Description
-----------

The :symbol:`bson_append_binary_uninit()` function is an alternative to :symbol:`bson_append_binary()` which allows applications to assemble the contents of the binary field within the :symbol:`bson_t`, without an additional temporary buffer.
On success, the caller MUST write to every byte of the binary data block if the resulting :symbol:`bson_t` is to be used.
The buffer that ``binary`` points to is only valid until the iterator's :symbol:`bson_t` is otherwise modified or freed.


Returns
-------

Returns ``true`` if the uninitialized ``binary`` item was appended. The function will fail if appending ``binary`` grows ``bson`` larger than INT32_MAX.
Loading