Object & Key-Value Management
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Object and Key-Value Management in libfastjson provides the core infrastructure for representing, manipulating, and storing JSON objects. The library implements a reference-counting model that allows for shared ownership of JSON structures, ensuring efficient memory management while providing a C-based representation of JSON data types. Sources: README.html, json_object.h:118-132
The system is designed for high-performance processing, utilizing optimized data structures such as paged child storage for object fields and specialized handling for small strings. It supports the creation of complex nested structures, including objects, arrays, and various primitive types like integers, doubles, and booleans. Sources: README.md, json_object_private.h:60-84
Core Data Structures
The fjson_object Structure
The central component of the management system is the fjson_object structure. It is a polymorphic container that uses a union to store different JSON types. Sources: json_object_private.h:60-84
The o_type field defines the specific JSON type of the instance, while the union o holds the actual value or structural metadata. Sources: json_object_private.h:62-83
Object Field Storage (c_obj)
Unlike traditional hash tables, libfastjson manages object key-value pairs using a paged linked-list structure. This approach balances memory overhead with allocation frequency. Sources: json_object.h:37-46, json_object_private.h:55-58
| Component | Description |
|---|---|
_fjson_child | Represents a single key-value pair, including flags for constant keys. |
_fjson_child_pg | A page containing a fixed array of FJSON_OBJECT_CHLD_PG_SIZE (default 8) children. |
nelem | The total number of active elements in the object. |
ndeleted | The count of deleted slots available for reuse within pages. |
Sources: json_object.h:46, json_object_private.h:44-58
Lifecycle and Reference Counting
The library utilizes an atomic reference counting mechanism to manage the memory of JSON objects. Objects are initialized with a reference count of 1 and are freed only when the count reaches zero. Sources: json_object.c:166-184, atomic.h:40-47
Key functions for lifecycle management:
fjson_object_get(): Increments the reference count. Sources: json_object.c:166-171fjson_object_put(): Decrements the reference count and invokes the internal_deletefunction if it reaching zero. Sources: json_object.c:173-182
Key-Value Operations
Adding and Replacing Fields
Field management is performed via fjson_object_object_add_ex and its wrapper fjson_object_object_add. The extended function allows performance optimizations through flags. Sources: json_object.c:292-315
- Flag
FJSON_OBJECT_ADD_KEY_IS_NEW: Bypasses the existence check, providing a speedup when keys are known to be unique. Sources: json_object.h:84-93 - Flag
FJSON_OBJECT_KEY_IS_CONSTANT: Preventsstrdup()of the key, assuming the provided pointer remains valid for the object's lifetime. Sources: json_object.h:94-108
Sources: json_object.c:254-315
Deleting Fields
When a key is deleted via fjson_object_object_del, the value's reference count is decremented. The slot is marked as NULL and the ndeleted counter is incremented, allowing future additions to reuse the slot without allocating new pages. Sources: json_object.c:355-368
Type-Specific Management
The system provides specialized constructors and accessors for different JSON types:
| JSON Type | Constructor | Accessor |
|---|---|---|
| Object | fjson_object_new_object() | fjson_object_object_get_ex() |
| Array | fjson_object_new_array() | fjson_object_array_get_idx() |
| String | fjson_object_new_string() | fjson_object_get_string() |
| Integer | fjson_object_new_int64() | fjson_object_get_int64() |
| Double | fjson_object_new_double() | fjson_object_get_double() |
| Boolean | fjson_object_new_boolean() | fjson_object_get_boolean() |
Sources: json_object.h:207-427
String Optimization
For performance, strings under 32 bytes (LEN_DIRECT_STRING_DATA) are stored directly within the object's structure rather than being allocated separately. Sources: json_object_private.h:23-23, 76-80
Serialization and Printing
The object management system includes an internal mechanism for stringification. Each object type registers a _to_json_string function pointer. Sources: json_object.c:196-207, json_object_private.h:35-38
The printing system supports various flags such as FJSON_TO_STRING_PRETTY for formatted output and FJSON_TO_STRING_NOZERO for optimized floating-point representation. Sources: json_print.c:451-470, json_object.h:60-75
Summary
Object & Key-Value Management in libfastjson provides a high-performance C implementation of JSON structures. By using a combination of atomic reference counting, paged field storage, and inline string optimization, the system achieves fast processing speeds and efficient memory usage suitable for heavy-duty log processing and data transformation tasks. Sources: README.md, json_object.c:26-30