Commit d8bbc77c authored by Matthias Clasen's avatar Matthias Clasen

GVariant: Convert docs to markdown

Specifically, convert the sections to markdown syntax.
parent 9b6cc973
...@@ -91,201 +91,168 @@ ...@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment