mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
GVariant: Convert docs to markdown
Specifically, convert the sections to markdown syntax.
This commit is contained in:
parent
9b6cc973a0
commit
d8bbc77cb3
357
glib/gvariant.c
357
glib/gvariant.c
@ -91,201 +91,168 @@
|
|||||||
* values. #GVariant includes a printer for this language and a parser
|
* values. #GVariant includes a printer for this language and a parser
|
||||||
* with type inferencing.
|
* with type inferencing.
|
||||||
*
|
*
|
||||||
* <refsect2>
|
* ## Memory Use
|
||||||
* <title>Memory Use</title>
|
*
|
||||||
* <para>
|
* #GVariant tries to be quite efficient with respect to memory use.
|
||||||
* #GVariant tries to be quite efficient with respect to memory use.
|
* This section gives a rough idea of how much memory is used by the
|
||||||
* This section gives a rough idea of how much memory is used by the
|
* current implementation. The information here is subject to change
|
||||||
* current implementation. The information here is subject to change
|
* in the future.
|
||||||
* in the future.
|
*
|
||||||
* </para>
|
* The memory allocated by #GVariant can be grouped into 4 broad
|
||||||
* <para>
|
* purposes: memory for serialised data, memory for the type
|
||||||
* The memory allocated by #GVariant can be grouped into 4 broad
|
* information cache, buffer management memory and memory for the
|
||||||
* purposes: memory for serialised data, memory for the type
|
* #GVariant structure itself.
|
||||||
* information cache, buffer management memory and memory for the
|
*
|
||||||
* #GVariant structure itself.
|
* ## Serialised Data Memory
|
||||||
* </para>
|
*
|
||||||
* <refsect3 id="gvariant-serialised-data-memory">
|
* This is the memory that is used for storing GVariant data in
|
||||||
* <title>Serialised Data Memory</title>
|
* serialised form. This is what would be sent over the network or
|
||||||
* <para>
|
* what would end up on disk.
|
||||||
* This is the memory that is used for storing GVariant data in
|
*
|
||||||
* serialised form. This is what would be sent over the network or
|
* The amount of memory required to store a boolean is 1 byte. 16,
|
||||||
* what would end up on disk.
|
* 32 and 64 bit integers and double precision floating point numbers
|
||||||
* </para>
|
* use their "natural" size. Strings (including object path and
|
||||||
* <para>
|
* signature strings) are stored with a nul terminator, and as such
|
||||||
* The amount of memory required to store a boolean is 1 byte. 16,
|
* use the length of the string plus 1 byte.
|
||||||
* 32 and 64 bit integers and double precision floating point numbers
|
*
|
||||||
* use their "natural" size. Strings (including object path and
|
* Maybe types use no space at all to represent the null value and
|
||||||
* signature strings) are stored with a nul terminator, and as such
|
* use the same amount of space (sometimes plus one byte) as the
|
||||||
* use the length of the string plus 1 byte.
|
* equivalent non-maybe-typed value to represent the non-null case.
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* Arrays use the amount of space required to store each of their
|
||||||
* Maybe types use no space at all to represent the null value and
|
* members, concatenated. Additionally, if the items stored in an
|
||||||
* use the same amount of space (sometimes plus one byte) as the
|
* array are not of a fixed-size (ie: strings, other arrays, etc)
|
||||||
* equivalent non-maybe-typed value to represent the non-null case.
|
* then an additional framing offset is stored for each item. The
|
||||||
* </para>
|
* size of this offset is either 1, 2 or 4 bytes depending on the
|
||||||
* <para>
|
* overall size of the container. Additionally, extra padding bytes
|
||||||
* Arrays use the amount of space required to store each of their
|
* are added as required for alignment of child values.
|
||||||
* members, concatenated. Additionally, if the items stored in an
|
*
|
||||||
* array are not of a fixed-size (ie: strings, other arrays, etc)
|
* Tuples (including dictionary entries) use the amount of space
|
||||||
* then an additional framing offset is stored for each item. The
|
* required to store each of their members, concatenated, plus one
|
||||||
* size of this offset is either 1, 2 or 4 bytes depending on the
|
* framing offset (as per arrays) for each non-fixed-sized item in
|
||||||
* overall size of the container. Additionally, extra padding bytes
|
* the tuple, except for the last one. Additionally, extra padding
|
||||||
* are added as required for alignment of child values.
|
* bytes are added as required for alignment of child values.
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* Variants use the same amount of space as the item inside of the
|
||||||
* Tuples (including dictionary entries) use the amount of space
|
* variant, plus 1 byte, plus the length of the type string for the
|
||||||
* required to store each of their members, concatenated, plus one
|
* item inside the variant.
|
||||||
* framing offset (as per arrays) for each non-fixed-sized item in
|
*
|
||||||
* the tuple, except for the last one. Additionally, extra padding
|
* As an example, consider a dictionary mapping strings to variants.
|
||||||
* bytes are added as required for alignment of child values.
|
* In the case that the dictionary is empty, 0 bytes are required for
|
||||||
* </para>
|
* the serialisation.
|
||||||
* <para>
|
*
|
||||||
* Variants use the same amount of space as the item inside of the
|
* If we add an item "width" that maps to the int32 value of 500 then
|
||||||
* variant, plus 1 byte, plus the length of the type string for the
|
* we will use 4 byte to store the int32 (so 6 for the variant
|
||||||
* item inside the variant.
|
* containing it) and 6 bytes for the string. The variant must be
|
||||||
* </para>
|
* aligned to 8 after the 6 bytes of the string, so that's 2 extra
|
||||||
* <para>
|
* bytes. 6 (string) + 2 (padding) + 6 (variant) is 14 bytes used
|
||||||
* As an example, consider a dictionary mapping strings to variants.
|
* for the dictionary entry. An additional 1 byte is added to the
|
||||||
* In the case that the dictionary is empty, 0 bytes are required for
|
* array as a framing offset making a total of 15 bytes.
|
||||||
* the serialisation.
|
*
|
||||||
* </para>
|
* If we add another entry, "title" that maps to a nullable string
|
||||||
* <para>
|
* that happens to have a value of null, then we use 0 bytes for the
|
||||||
* If we add an item "width" that maps to the int32 value of 500 then
|
* null value (and 3 bytes for the variant to contain it along with
|
||||||
* we will use 4 byte to store the int32 (so 6 for the variant
|
* its type string) plus 6 bytes for the string. Again, we need 2
|
||||||
* containing it) and 6 bytes for the string. The variant must be
|
* padding bytes. That makes a total of 6 + 2 + 3 = 11 bytes.
|
||||||
* aligned to 8 after the 6 bytes of the string, so that's 2 extra
|
*
|
||||||
* bytes. 6 (string) + 2 (padding) + 6 (variant) is 14 bytes used
|
* We now require extra padding between the two items in the array.
|
||||||
* for the dictionary entry. An additional 1 byte is added to the
|
* After the 14 bytes of the first item, that's 2 bytes required. We
|
||||||
* array as a framing offset making a total of 15 bytes.
|
* now require 2 framing offsets for an extra two bytes. 14 + 2 + 11
|
||||||
* </para>
|
* + 2 = 29 bytes to encode the entire two-item dictionary.
|
||||||
* <para>
|
*
|
||||||
* If we add another entry, "title" that maps to a nullable string
|
* ## Type Information Cache
|
||||||
* that happens to have a value of null, then we use 0 bytes for the
|
*
|
||||||
* null value (and 3 bytes for the variant to contain it along with
|
* For each GVariant type that currently exists in the program a type
|
||||||
* its type string) plus 6 bytes for the string. Again, we need 2
|
* information structure is kept in the type information cache. The
|
||||||
* padding bytes. That makes a total of 6 + 2 + 3 = 11 bytes.
|
* type information structure is required for rapid deserialisation.
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* Continuing with the above example, if a #GVariant exists with the
|
||||||
* We now require extra padding between the two items in the array.
|
* type "a{sv}" then a type information struct will exist for
|
||||||
* After the 14 bytes of the first item, that's 2 bytes required. We
|
* "a{sv}", "{sv}", "s", and "v". Multiple uses of the same type
|
||||||
* now require 2 framing offsets for an extra two bytes. 14 + 2 + 11
|
* will share the same type information. Additionally, all
|
||||||
* + 2 = 29 bytes to encode the entire two-item dictionary.
|
* single-digit types are stored in read-only static memory and do
|
||||||
* </para>
|
* not contribute to the writable memory footprint of a program using
|
||||||
* </refsect3>
|
* #GVariant.
|
||||||
* <refsect3>
|
*
|
||||||
* <title>Type Information Cache</title>
|
* Aside from the type information structures stored in read-only
|
||||||
* <para>
|
* memory, there are two forms of type information. One is used for
|
||||||
* For each GVariant type that currently exists in the program a type
|
* container types where there is a single element type: arrays and
|
||||||
* information structure is kept in the type information cache. The
|
* maybe types. The other is used for container types where there
|
||||||
* type information structure is required for rapid deserialisation.
|
* are multiple element types: tuples and dictionary entries.
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* Array type info structures are 6 * sizeof (void *), plus the
|
||||||
* Continuing with the above example, if a #GVariant exists with the
|
* memory required to store the type string itself. This means that
|
||||||
* type "a{sv}" then a type information struct will exist for
|
* on 32-bit systems, the cache entry for "a{sv}" would require 30
|
||||||
* "a{sv}", "{sv}", "s", and "v". Multiple uses of the same type
|
* bytes of memory (plus malloc overhead).
|
||||||
* will share the same type information. Additionally, all
|
*
|
||||||
* single-digit types are stored in read-only static memory and do
|
* Tuple type info structures are 6 * sizeof (void *), plus 4 *
|
||||||
* not contribute to the writable memory footprint of a program using
|
* sizeof (void *) for each item in the tuple, plus the memory
|
||||||
* #GVariant.
|
* required to store the type string itself. A 2-item tuple, for
|
||||||
* </para>
|
* example, would have a type information structure that consumed
|
||||||
* <para>
|
* writable memory in the size of 14 * sizeof (void *) (plus type
|
||||||
* Aside from the type information structures stored in read-only
|
* string) This means that on 32-bit systems, the cache entry for
|
||||||
* memory, there are two forms of type information. One is used for
|
* "{sv}" would require 61 bytes of memory (plus malloc overhead).
|
||||||
* container types where there is a single element type: arrays and
|
*
|
||||||
* maybe types. The other is used for container types where there
|
* This means that in total, for our "a{sv}" example, 91 bytes of
|
||||||
* are multiple element types: tuples and dictionary entries.
|
* type information would be allocated.
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* The type information cache, additionally, uses a #GHashTable to
|
||||||
* Array type info structures are 6 * sizeof (void *), plus the
|
* store and lookup the cached items and stores a pointer to this
|
||||||
* memory required to store the type string itself. This means that
|
* hash table in static storage. The hash table is freed when there
|
||||||
* on 32-bit systems, the cache entry for "a{sv}" would require 30
|
* are zero items in the type cache.
|
||||||
* bytes of memory (plus malloc overhead).
|
*
|
||||||
* </para>
|
* Although these sizes may seem large it is important to remember
|
||||||
* <para>
|
* that a program will probably only have a very small number of
|
||||||
* Tuple type info structures are 6 * sizeof (void *), plus 4 *
|
* different types of values in it and that only one type information
|
||||||
* sizeof (void *) for each item in the tuple, plus the memory
|
* structure is required for many different values of the same type.
|
||||||
* required to store the type string itself. A 2-item tuple, for
|
*
|
||||||
* example, would have a type information structure that consumed
|
* ## Buffer Management Memory
|
||||||
* writable memory in the size of 14 * sizeof (void *) (plus type
|
*
|
||||||
* string) This means that on 32-bit systems, the cache entry for
|
* #GVariant uses an internal buffer management structure to deal
|
||||||
* "{sv}" would require 61 bytes of memory (plus malloc overhead).
|
* with the various different possible sources of serialised data
|
||||||
* </para>
|
* that it uses. The buffer is responsible for ensuring that the
|
||||||
* <para>
|
* correct call is made when the data is no longer in use by
|
||||||
* This means that in total, for our "a{sv}" example, 91 bytes of
|
* #GVariant. This may involve a g_free() or a g_slice_free() or
|
||||||
* type information would be allocated.
|
* even g_mapped_file_unref().
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* One buffer management structure is used for each chunk of
|
||||||
* The type information cache, additionally, uses a #GHashTable to
|
* serialised data. The size of the buffer management structure
|
||||||
* store and lookup the cached items and stores a pointer to this
|
* is 4 * (void *). On 32-bit systems, that's 16 bytes.
|
||||||
* hash table in static storage. The hash table is freed when there
|
*
|
||||||
* are zero items in the type cache.
|
* ## GVariant structure
|
||||||
* </para>
|
*
|
||||||
* <para>
|
* The size of a #GVariant structure is 6 * (void *). On 32-bit
|
||||||
* Although these sizes may seem large it is important to remember
|
* systems, that's 24 bytes.
|
||||||
* that a program will probably only have a very small number of
|
*
|
||||||
* different types of values in it and that only one type information
|
* #GVariant structures only exist if they are explicitly created
|
||||||
* structure is required for many different values of the same type.
|
* with API calls. For example, if a #GVariant is constructed out of
|
||||||
* </para>
|
* serialised data for the example given above (with the dictionary)
|
||||||
* </refsect3>
|
* then although there are 9 individual values that comprise the
|
||||||
* <refsect3>
|
* entire dictionary (two keys, two values, two variants containing
|
||||||
* <title>Buffer Management Memory</title>
|
* the values, two dictionary entries, plus the dictionary itself),
|
||||||
* <para>
|
* only 1 #GVariant instance exists -- the one referring to the
|
||||||
* #GVariant uses an internal buffer management structure to deal
|
* dictionary.
|
||||||
* with the various different possible sources of serialised data
|
*
|
||||||
* that it uses. The buffer is responsible for ensuring that the
|
* If calls are made to start accessing the other values then
|
||||||
* correct call is made when the data is no longer in use by
|
* #GVariant instances will exist for those values only for as long
|
||||||
* #GVariant. This may involve a g_free() or a g_slice_free() or
|
* as they are in use (ie: until you call g_variant_unref()). The
|
||||||
* even g_mapped_file_unref().
|
* type information is shared. The serialised data and the buffer
|
||||||
* </para>
|
* management structure for that serialised data is shared by the
|
||||||
* <para>
|
* child.
|
||||||
* One buffer management structure is used for each chunk of
|
*
|
||||||
* serialised data. The size of the buffer management structure is 4
|
* ## Summary
|
||||||
* * (void *). On 32bit systems, that's 16 bytes.
|
*
|
||||||
* </para>
|
* To put the entire example together, for our dictionary mapping
|
||||||
* </refsect3>
|
* strings to variants (with two entries, as given above), we are
|
||||||
* <refsect3>
|
* using 91 bytes of memory for type information, 29 byes of memory
|
||||||
* <title>GVariant structure</title>
|
* for the serialised data, 16 bytes for buffer management and 24
|
||||||
* <para>
|
* bytes for the #GVariant instance, or a total of 160 bytes, plus
|
||||||
* The size of a #GVariant structure is 6 * (void *). On 32 bit
|
* malloc overhead. If we were to use g_variant_get_child_value() to
|
||||||
* systems, that's 24 bytes.
|
* access the two dictionary entries, we would use an additional 48
|
||||||
* </para>
|
* bytes. If we were to have other dictionaries of the same type, we
|
||||||
* <para>
|
* would use more memory for the serialised data and buffer
|
||||||
* #GVariant structures only exist if they are explicitly created
|
* management for those dictionaries, but the type information would
|
||||||
* with API calls. For example, if a #GVariant is constructed out of
|
* be shared.
|
||||||
* serialised data for the example given above (with the dictionary)
|
|
||||||
* then although there are 9 individual values that comprise the
|
|
||||||
* entire dictionary (two keys, two values, two variants containing
|
|
||||||
* the values, two dictionary entries, plus the dictionary itself),
|
|
||||||
* only 1 #GVariant instance exists -- the one referring to the
|
|
||||||
* dictionary.
|
|
||||||
* </para>
|
|
||||||
* <para>
|
|
||||||
* If calls are made to start accessing the other values then
|
|
||||||
* #GVariant instances will exist for those values only for as long
|
|
||||||
* as they are in use (ie: until you call g_variant_unref()). The
|
|
||||||
* type information is shared. The serialised data and the buffer
|
|
||||||
* management structure for that serialised data is shared by the
|
|
||||||
* child.
|
|
||||||
* </para>
|
|
||||||
* </refsect3>
|
|
||||||
* <refsect3>
|
|
||||||
* <title>Summary</title>
|
|
||||||
* <para>
|
|
||||||
* To put the entire example together, for our dictionary mapping
|
|
||||||
* strings to variants (with two entries, as given above), we are
|
|
||||||
* using 91 bytes of memory for type information, 29 byes of memory
|
|
||||||
* for the serialised data, 16 bytes for buffer management and 24
|
|
||||||
* bytes for the #GVariant instance, or a total of 160 bytes, plus
|
|
||||||
* malloc overhead. If we were to use g_variant_get_child_value() to
|
|
||||||
* access the two dictionary entries, we would use an additional 48
|
|
||||||
* bytes. If we were to have other dictionaries of the same type, we
|
|
||||||
* would use more memory for the serialised data and buffer
|
|
||||||
* management for those dictionaries, but the type information would
|
|
||||||
* be shared.
|
|
||||||
* </para>
|
|
||||||
* </refsect3>
|
|
||||||
* </refsect2>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* definition of GVariant structure is in gvariant-core.c */
|
/* definition of GVariant structure is in gvariant-core.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user