Skip to content

claujson/claujson2-document

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

6 Commits
ย 
ย 
ย 
ย 

Repository files navigation

claujson2-document

first check!

01. 64bit only
02. has my own memory allocator.
03. C++14~ 
04. experimental!
05. Array has my_own_vector<_Value>
06. Object has my_own_vector<Pair<_Value, _Value>> (not a std::map!)
07. in Object, key can be dupplicated, are not sorted, just in order of input.
08. scanning - modified? simdjson, parsing - parallel 
09. it is not read-only!
10. _Value <- json_Value, (in destructor, no remove data(Array or Object!), no copy, only move or clone!
11. Value <- wrap _Value, (in destructor, remove data(Array or Object!)

claujson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฌธ์„œ - using claude

C++17 ๊ธฐ๋ฐ˜์˜ ๊ณ ์„ฑ๋Šฅ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ JSON ํŒŒ์„œ ๋ฐ ์ง๋ ฌํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ


๋ชฉ์ฐจ

  1. ๊ฐœ์š”
  2. ์•„ํ‚คํ…์ฒ˜ ๊ตฌ์กฐ
  3. ํ•ต์‹ฌ ํด๋ž˜์Šค
  4. ํŒŒ์„œ ๋ฐ ์ง๋ ฌํ™”
  5. ์œ ํ‹ธ๋ฆฌํ‹ฐ
  6. ํƒ€์ž… ์‹œ์Šคํ…œ
  7. ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
  8. ์‚ฌ์šฉ ์˜ˆ์‹œ
  9. ๋‚ด๋ถ€ ๊ตฌํ˜„ ์ƒ์„ธ

๊ฐœ์š”

claujson์€ simdjson์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋œ C++ JSON ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ฃผ์š” ํŠน์ง•:

  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํŒŒ์‹ฑ: JSON์„ ์—ฌ๋Ÿฌ ์ฒญํฌ๋กœ ๋ถ„ํ• ํ•˜์—ฌ ๋ณ‘๋ ฌ ํŒŒ์‹ฑ ํ›„ ๋ณ‘ํ•ฉ
  • Arena ๊ธฐ๋ฐ˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ: ๋ณ„๋„ ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์‚ฌ์šฉํ•˜์—ฌ ํ• ๋‹น/ํ•ด์ œ ์˜ค๋ฒ„ํ—ค๋“œ ์ตœ์†Œํ™”
  • ์ด๋™ ์ „์šฉ(Move-only) ์„ค๊ณ„: _Value, Value ๋“ฑ์˜ ํ•ต์‹ฌ ํƒ€์ž…์€ ๋ณต์‚ฌ ๋ถˆ๊ฐ€, ์ด๋™๋งŒ ๊ฐ€๋Šฅ
  • Short String ์ตœ์ ํ™”: 11๋ฐ”์ดํŠธ ์ดํ•˜์˜ ๋ฌธ์ž์—ด์€ ํž™ ํ• ๋‹น ์—†์ด ์ธ๋ผ์ธ ์ €์žฅ
  • ๋ณ‘๋ ฌ ์ง๋ ฌํ™”: JSON ํŠธ๋ฆฌ๋ฅผ ๋ถ„ํ• ํ•˜์—ฌ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ ๋™์‹œ ์ง๋ ฌํ™”

์•„ํ‚คํ…์ฒ˜ ๊ตฌ์กฐ

claujson
โ”œโ”€โ”€ claujson_internal.h    # ๊ธฐ๋ฐ˜ ํƒ€์ž…, Arena, my_vector, Log ๋“ฑ
โ”œโ”€โ”€ claujson_string.h      # String ํด๋ž˜์Šค (SSO ํฌํ•จ)
โ”œโ”€โ”€ claujson.h             # _Value, Value, Document, StructuredPtr, parser, writer
โ”œโ”€โ”€ claujson_array.h/.cpp  # Array ํด๋ž˜์Šค
โ”œโ”€โ”€ claujson_object.h/.cpp # Object ํด๋ž˜์Šค
โ”œโ”€โ”€ claujson_partialjson.h/.cpp # PartialJson (ํŒŒ์‹ฑ ๋‚ด๋ถ€์šฉ)
โ””โ”€โ”€ claujson.cpp           # ํŒŒ์‹ฑ/์ง๋ ฌํ™” ํ•ต์‹ฌ ๊ตฌํ˜„, diff/patch

์˜์กด ๊ด€๊ณ„

_Value
 โ”œโ”€โ”€ Array*      (_array_ptr)
 โ”œโ”€โ”€ Object*     (_obj_ptr)
 โ”œโ”€โ”€ PartialJson* (_pj_ptr)
 โ””โ”€โ”€ String*     (_str_val)

StructuredPtr
 โ””โ”€โ”€ Array* / Object* / PartialJson* (union)

Document
 โ”œโ”€โ”€ _Value (๋ฃจํŠธ ๊ฐ’)
 โ””โ”€โ”€ Arena* (๋ฉ”๋ชจ๋ฆฌ ํ’€)

ํ•ต์‹ฌ ํด๋ž˜์Šค

_Value

JSON์˜ ๋‹จ์ผ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋Š” ํ•ต์‹ฌ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ •์ˆ˜, ์‹ค์ˆ˜, ๋ถˆ๋ฆฌ์–ธ, ๋ฌธ์ž์—ด, null, ๋ฐฐ์—ด, ๊ฐ์ฒด๋ฅผ ๋ชจ๋‘ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

ํ—ค๋”: claujson.h

์ฃผ์š” ํŠน์„ฑ

  • ๋ณต์‚ฌ ๋ถˆ๊ฐ€: _Value(const _Value&) = delete
  • ์ด๋™ ๊ฐ€๋Šฅ: _Value(_Value&&) noexcept
  • ๋‚ด๋ถ€์ ์œผ๋กœ union์„ ํ†ตํ•ด ํƒ€์ž…๋ณ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ  ์ €์žฅ

๋‚ด๋ถ€ ์ €์žฅ ๊ตฌ์กฐ

union {
    int64_t   _int_val;
    uint64_t  _uint_val;
    double    _float_val;
    Array*    _array_ptr;
    Object*   _obj_ptr;
    PartialJson* _pj_ptr;
    String*   _str_val;
    bool      _bool_val;
};
_ValueType _type;

์ƒ์„ฑ์ž

์ƒ์„ฑ์ž ์„ค๋ช…
_Value() ๊ธฐ๋ณธ ์ƒ์„ฑ์ž (NONE ํƒ€์ž…)
_Value(int x) ์ •์ˆ˜ ๊ฐ’
_Value(unsigned int x) ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜
_Value(int64_t x) 64๋น„ํŠธ ์ •์ˆ˜
_Value(uint64_t x) 64๋น„ํŠธ ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜
_Value(double x) ๋ถ€๋™์†Œ์ˆ˜์ 
_Value(bool x) ๋ถˆ๋ฆฌ์–ธ
_Value(std::nullptr_t x) null ๊ฐ’
_Value(Arena* pool, StringView x) ๋ฌธ์ž์—ด (UTF-8 ๊ฒ€์ฆ ํฌํ•จ)
_Value(Arena* pool, const char* x) C ๋ฌธ์ž์—ด
_Value(Array* x) ๋ฐฐ์—ด ํฌ์ธํ„ฐ๋กœ๋ถ€ํ„ฐ
_Value(Object* x) ๊ฐ์ฒด ํฌ์ธํ„ฐ๋กœ๋ถ€ํ„ฐ

ํƒ€์ž… ํ™•์ธ ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ์„ค๋ช…
is_valid() bool ์œ ํšจํ•œ ๊ฐ’์ธ์ง€ ํ™•์ธ
is_null() bool null ํƒ€์ž…์ธ์ง€ ํ™•์ธ
is_primitive() bool ๊ธฐ๋ณธ ํƒ€์ž…์ธ์ง€ ํ™•์ธ
is_structured() bool ๋ฐฐ์—ด ๋˜๋Š” ๊ฐ์ฒด์ธ์ง€ ํ™•์ธ
is_array() bool ๋ฐฐ์—ด์ธ์ง€ ํ™•์ธ
is_object() bool ๊ฐ์ฒด์ธ์ง€ ํ™•์ธ
is_int() bool 64๋น„ํŠธ ์ •์ˆ˜์ธ์ง€ ํ™•์ธ
is_uint() bool ๋ถ€ํ˜ธ ์—†๋Š” 64๋น„ํŠธ ์ •์ˆ˜์ธ์ง€ ํ™•์ธ
is_float() bool ๋ถ€๋™์†Œ์ˆ˜์ ์ธ์ง€ ํ™•์ธ
is_number() bool ์ˆซ์ž ํƒ€์ž…์ธ์ง€ ํ™•์ธ (int, uint, float)
is_bool() bool ๋ถˆ๋ฆฌ์–ธ์ธ์ง€ ํ™•์ธ
is_str() bool ๋ฌธ์ž์—ด์ธ์ง€ ํ™•์ธ
is_virtual() bool ๊ฐ€์ƒ ๋…ธ๋“œ์ธ์ง€ ํ™•์ธ (๋‚ด๋ถ€ ํŒŒ์‹ฑ์šฉ)
is_partial_json() bool ๋ถ€๋ถ„ JSON์ธ์ง€ ํ™•์ธ (๋‚ด๋ถ€์šฉ)

๊ฐ’ ์ ‘๊ทผ ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ์„ค๋ช…
int_val() int64_t ์ •์ˆ˜ ๊ฐ’ ๋ฐ˜ํ™˜
uint_val() uint64_t ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜ ๊ฐ’ ๋ฐ˜ํ™˜
float_val() double ๋ถ€๋™์†Œ์ˆ˜์  ๊ฐ’ ๋ฐ˜ํ™˜
bool_val() bool ๋ถˆ๋ฆฌ์–ธ ๊ฐ’ ๋ฐ˜ํ™˜
str_val() String& ๋ฌธ์ž์—ด ๊ฐ์ฒด ์ฐธ์กฐ ๋ฐ˜ํ™˜
get_integer() int64_t ์ •์ˆ˜ ๊ฐ’ ๋ฐ˜ํ™˜ (int_val() ๋ณ„์นญ)
get_unsigned_integer() uint64_t ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜ ๋ฐ˜ํ™˜
get_floating() double ๋ถ€๋™์†Œ์ˆ˜์  ๋ฐ˜ํ™˜
get_boolean() bool ๋ถˆ๋ฆฌ์–ธ ๋ฐ˜ํ™˜
get_string() String& ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜
get_number<T>() T ์ˆซ์ž๋ฅผ ์ง€์ • ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ ๋ฐ˜ํ™˜

๊ตฌ์กฐ์ฒด ์ ‘๊ทผ ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ์„ค๋ช…
as_array() Array* Array ํฌ์ธํ„ฐ ๋ฐ˜ํ™˜ (๋ฐฐ์—ด์ด ์•„๋‹ˆ๋ฉด nullptr)
as_object() Object* Object ํฌ์ธํ„ฐ ๋ฐ˜ํ™˜ (๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ฉด nullptr)
as_partial_json() PartialJson* PartialJson ํฌ์ธํ„ฐ ๋ฐ˜ํ™˜
as_structured() StructuredPtr ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ ๋ž˜ํผ ๋ฐ˜ํ™˜
as_structured_ptr() StructuredPtr ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ ๋ž˜ํผ ๋ฐ˜ํ™˜

์—ฐ์‚ฐ์ž

์—ฐ์‚ฐ์ž ์„ค๋ช…
operator[](uint64_t idx) ์ธ๋ฑ์Šค๋กœ ์ž์‹ ๊ฐ’ ์ ‘๊ทผ
operator[](const _Value& key) ํ‚ค๋กœ ์ž์‹ ๊ฐ’ ์ ‘๊ทผ (๊ฐ์ฒด)
operator bool() ์œ ํšจ์„ฑ ํ™•์ธ
operator== / operator!= ๋น„๊ต
operator< ์ •๋ ฌ์šฉ ๋น„๊ต
operator=(_Value&&) ์ด๋™ ๋Œ€์ž…

๊ฐ’ ์„ค์ • ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
set_int(long long x) ์ •์ˆ˜ ๊ฐ’ ์„ค์ •
set_uint(unsigned long long x) ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜ ์„ค์ •
set_float(double x) ๋ถ€๋™์†Œ์ˆ˜์  ์„ค์ •
set_str(Arena*, const char*, uint64_t) ๋ฌธ์ž์—ด ์„ค์ • (UTF-8 ๊ฒ€์ฆ, ์ด์Šค์ผ€์ดํ”„ ์ฒ˜๋ฆฌ)
set_bool(bool x) ๋ถˆ๋ฆฌ์–ธ ์„ค์ •
set_null() null ์„ค์ •
set_none() NONE ํƒ€์ž…์œผ๋กœ ์ดˆ๊ธฐํ™”

JSON ํฌ์ธํ„ฐ ์ ‘๊ทผ

_Value& json_pointerB(const my_vector<_Value>& routeVec);
const _Value& json_pointerB(const my_vector<_Value>& routeVec) const;

๊ฒฝ๋กœ(route)๋ฅผ ๋”ฐ๋ผ ์ค‘์ฒฉ๋œ ๊ฐ’์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด์€ ์ธ๋ฑ์Šค(์ •์ˆ˜), ๊ฐ์ฒด๋Š” ํ‚ค(๋ฌธ์ž์—ด)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ณต์ œ

_Value clone(Arena* pool) const;

๊ฐ’์„ ๊นŠ์€ ๋ณต์‚ฌ(deep copy)ํ•ฉ๋‹ˆ๋‹ค. pool์ด ์ œ๊ณต๋˜๋ฉด Arena์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.


Array

JSON ๋ฐฐ์—ด์„ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson_array.h

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
static _Value Make(Arena* pool) ์ผ๋ฐ˜ ๋ฐฐ์—ด ์ƒ์„ฑ
static _Value MakeVirtual(Arena* pool) ๊ฐ€์ƒ ๋ฐฐ์—ด ์ƒ์„ฑ (๋‚ด๋ถ€ ํŒŒ์‹ฑ์šฉ)

์ฃผ์š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ์„ค๋ช…
size() uint64_t ์›์†Œ ์ˆ˜ ๋ฐ˜ํ™˜
empty() bool ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธ
get_data_size() uint64_t ์›์†Œ ์ˆ˜ ๋ฐ˜ํ™˜
get_value_list(idx) _Value& ์ธ๋ฑ์Šค๋กœ ๊ฐ’ ์ ‘๊ทผ
operator[](idx) _Value& ์ธ๋ฑ์Šค๋กœ ๊ฐ’ ์ ‘๊ทผ
add_element(Value val) bool ์›์†Œ ์ถ”๊ฐ€
assign_element(idx, Value val) bool ์ธ๋ฑ์Šค ์œ„์น˜์— ๊ฐ’ ๋Œ€์ž…
insert(idx, Value val) bool ์ธ๋ฑ์Šค ์œ„์น˜์— ์‚ฝ์ž…
erase(idx, bool real) void ์ธ๋ฑ์Šค ์œ„์น˜ ์›์†Œ ์‚ญ์ œ
erase(const _Value&, bool real) void ๊ฐ’์œผ๋กœ ๊ฒ€์ƒ‰ ํ›„ ์‚ญ์ œ
find(const _Value&, start) uint64_t ๊ฐ’ ๊ฒ€์ƒ‰, ์—†์œผ๋ฉด npos
clear() void ์ „์ฒด ์ดˆ๊ธฐํ™”
clear(idx) void ์ธ๋ฑ์Šค ์œ„์น˜ ์›์†Œ ์ดˆ๊ธฐํ™”
reserve_data_list(len) void ์šฉ๋Ÿ‰ ์˜ˆ์•ฝ
clone(Arena*) _Value ๊นŠ์€ ๋ณต์‚ฌ
is_virtual() bool ๊ฐ€์ƒ ๋…ธ๋“œ ์—ฌ๋ถ€
get_parent() StructuredPtr ๋ถ€๋ชจ ๋…ธ๋“œ ๋ฐ˜ํ™˜
set_parent(StructuredPtr) void ๋ถ€๋ชจ ๋…ธ๋“œ ์„ค์ •

์ดํ„ฐ๋ ˆ์ดํ„ฐ

_ValueIterator  begin();   // _Value*
_ValueIterator  end();
_ConstValueIterator begin() const;
_ConstValueIterator end()   const;

Object

JSON ๊ฐ์ฒด(ํ‚ค-๊ฐ’ ์Œ์˜ ์ปฌ๋ ‰์…˜)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson_object.h

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
static _Value Make(Arena* pool) ์ผ๋ฐ˜ ๊ฐ์ฒด ์ƒ์„ฑ
static _Value MakeVirtual(Arena* pool) ๊ฐ€์ƒ ๊ฐ์ฒด ์ƒ์„ฑ (๋‚ด๋ถ€ ํŒŒ์‹ฑ์šฉ)

์ฃผ์š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ์„ค๋ช…
size() uint64_t ํ‚ค-๊ฐ’ ์Œ์˜ ์ˆ˜ ๋ฐ˜ํ™˜
empty() bool ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธ
get_data_size() uint64_t ํ‚ค-๊ฐ’ ์Œ์˜ ์ˆ˜ ๋ฐ˜ํ™˜
get_value_list(idx) _Value& ์ธ๋ฑ์Šค๋กœ ๊ฐ’ ์ ‘๊ทผ
get_key_list(idx) _Value& ์ธ๋ฑ์Šค๋กœ ํ‚ค ์ ‘๊ทผ (private)
get_const_key_list(idx) const _Value& ์ธ๋ฑ์Šค๋กœ ํ‚ค ์ฝ๊ธฐ
operator[](const _Value& key) _Value& ํ‚ค๋กœ ๊ฐ’ ์ ‘๊ทผ
operator[](uint64_t idx) _Value& ์ธ๋ฑ์Šค๋กœ ๊ฐ’ ์ ‘๊ทผ
find(const _Value& key) uint64_t ํ‚ค ๊ฒ€์ƒ‰, ์—†์œผ๋ฉด npos
add_element(Value key, Value val) bool ํ‚ค-๊ฐ’ ์Œ ์ถ”๊ฐ€
assign_value_element(idx, Value val) bool ์ธ๋ฑ์Šค ์œ„์น˜์— ๊ฐ’ ๋Œ€์ž…
change_key(const _Value&, Value) bool ํ‚ค ๋ณ€๊ฒฝ
change_key(uint64_t idx, Value) bool ์ธ๋ฑ์Šค๋กœ ํ‚ค ๋ณ€๊ฒฝ
erase(const _Value& key, bool real) void ํ‚ค๋กœ ์‚ญ์ œ
erase(uint64_t idx, bool real) void ์ธ๋ฑ์Šค๋กœ ์‚ญ์ œ
chk_key_dup(uint64_t*) bool ํ‚ค ์ค‘๋ณต ํ™•์ธ
clear() void ์ „์ฒด ์ดˆ๊ธฐํ™”
reserve_data_list(len) void ์šฉ๋Ÿ‰ ์˜ˆ์•ฝ
clone(Arena*) _Value ๊นŠ์€ ๋ณต์‚ฌ

์ดํ„ฐ๋ ˆ์ดํ„ฐ

// Pair<_Value, _Value>*  (ํ‚ค-๊ฐ’ ์Œ ํฌ์ธํ„ฐ)
_ValueIterator      begin();
_ValueIterator      end();
_ConstValueIterator begin() const;
_ConstValueIterator end()   const;

PartialJson

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํŒŒ์‹ฑ ๊ณผ์ •์—์„œ ๋ถ„ํ• ๋œ JSON ์กฐ๊ฐ์„ ์ž„์‹œ๋กœ ๋ณด๊ด€ํ•˜๋Š” ๋‚ด๋ถ€ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson_partialjson.h

์ฃผ์˜: ์ด ํด๋ž˜์Šค๋Š” LoadData / LoadData2 ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๋Š” ์ง์ ‘ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŠน์ง•

  • ๋ฐฐ์—ด(arr_vec) ๋˜๋Š” ๊ฐ์ฒด(obj_data) ์ค‘ ํ•˜๋‚˜๋กœ ์ž‘๋™
  • virtualJson: ๊ฐ€์ƒ ๋ฃจํŠธ ๋…ธ๋“œ(๋ถ„ํ•  ๊ฒฝ๊ณ„์—์„œ ๋ฐœ์ƒ)๋ฅผ ๋ณด๊ด€
  • ๋ถ€๋ชจ๊ฐ€ nullptr์ธ ์ตœ์ƒ์œ„ ๋ถ€๋ถ„ JSON

์ฃผ์š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
add_array_element(Value val) ๋ฐฐ์—ด ์›์†Œ ์ถ”๊ฐ€
add_object_element(Value key, Value val) ๊ฐ์ฒด ์›์†Œ ์ถ”๊ฐ€
get_data_size() ๋ณด๊ด€ ์ค‘์ธ ์›์†Œ ์ˆ˜
get_value_list(idx) ์ธ๋ฑ์Šค๋กœ ๊ฐ’ ์ ‘๊ทผ
get_key_list(idx) ์ธ๋ฑ์Šค๋กœ ํ‚ค ์ ‘๊ทผ
MergeWith(Array*, int) Array์™€ ๋ณ‘ํ•ฉ
MergeWith(PartialJson*, int) PartialJson๊ณผ ๋ณ‘ํ•ฉ

StructuredPtr

Array*, Object*, PartialJson*๋ฅผ ํ•˜๋‚˜์˜ ํƒ€์ž…์œผ๋กœ ๋‹ค๋ฃจ๋Š” ํฌ์ธํ„ฐ ๋ž˜ํผ์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson.h

์ƒ์„ฑ์ž

StructuredPtr()                    // nullptr
StructuredPtr(Array* arr)          // type = 1
StructuredPtr(Object* obj)         // type = 2
StructuredPtr(PartialJson* pj)     // type = 3
StructuredPtr(_Value& x)           // _Value๋กœ๋ถ€ํ„ฐ ์ž๋™ ํŒ๋ณ„
StructuredPtr(const _Value& x)

ํƒ€์ž… ํ™•์ธ

bool is_array()        const;
bool is_object()       const;
bool is_partial_json() const;
bool is_nullptr()      const;
bool is_user_type()    const;  // array || object
bool is_virtual()      const;
explicit operator bool() const;

์ฃผ์š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
size() / empty() ํฌ๊ธฐ ํ™•์ธ
get_data_size() ์›์†Œ ์ˆ˜
get_value_list(idx) ๊ฐ’ ์ ‘๊ทผ
get_key_list(idx) ํ‚ค ์ ‘๊ทผ (๊ฐ์ฒด/PartialJson)
get_const_key_list(idx) ํ‚ค ์ฝ๊ธฐ ์ „์šฉ ์ ‘๊ทผ
add_array_element(Value) ๋ฐฐ์—ด์— ์›์†Œ ์ถ”๊ฐ€
add_object_element(Value, Value) ๊ฐ์ฒด์— ํ‚ค-๊ฐ’ ์ถ”๊ฐ€
operator[](const _Value&) ํ‚ค๋กœ ๊ฐ’ ์ ‘๊ทผ
operator[](uint64_t) ์ธ๋ฑ์Šค๋กœ ๊ฐ’ ์ ‘๊ทผ
find_by_key(const _Value&) ํ‚ค ๊ฒ€์ƒ‰
find_by_value(const _Value&, start) ๊ฐ’ ๊ฒ€์ƒ‰
insert(idx, Value) ๋ฐฐ์—ด์— ์‚ฝ์ž…
erase(idx, bool) ์ธ๋ฑ์Šค๋กœ ์‚ญ์ œ
erase(const _Value&, bool) ํ‚ค๋กœ ์‚ญ์ œ
assign_value(idx, Value) ์ธ๋ฑ์Šค ์œ„์น˜์— ๊ฐ’ ๋Œ€์ž…
change_key(const _Value&, Value&&) ํ‚ค ๋ณ€๊ฒฝ
change_key(uint64_t, Value&&) ์ธ๋ฑ์Šค๋กœ ํ‚ค ๋ณ€๊ฒฝ
chk_key_dup(uint64_t*) ํ‚ค ์ค‘๋ณต ํ™•์ธ
get_parent() ๋ถ€๋ชจ ๋…ธ๋“œ ๋ฐ˜ํ™˜
null_parent() ๋ถ€๋ชจ ํฌ์ธํ„ฐ null๋กœ ์„ค์ •
MergeWith(StructuredPtr, int) ๋‹ค๋ฅธ ๊ตฌ์กฐ์ฒด์™€ ๋ณ‘ํ•ฉ
reserve_data_list(sz) ์šฉ๋Ÿ‰ ์˜ˆ์•ฝ
clear() ์ „์ฒด ์ดˆ๊ธฐํ™”
clear(idx) ํŠน์ • ์ธ๋ฑ์Šค ์ดˆ๊ธฐํ™”
Delete() ํฌ์ธํ„ฐ delete ๋ฐ nullptr ์„ค์ •
get_pool() Arena ํฌ์ธํ„ฐ ๋ฐ˜ํ™˜
has_pool() Arena ์‚ฌ์šฉ ์—ฌ๋ถ€

Document

ํŒŒ์‹ฑ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์œ ํ•˜๋Š” ์ตœ์ƒ์œ„ ์ปจํ…Œ์ด๋„ˆ์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson.h

class Document {
    _Value x;    // ๋ฃจํŠธ JSON ๊ฐ’
    Arena* pool; // ๋ฉ”๋ชจ๋ฆฌ ํ’€
};

์ƒ์„ฑ์ž

Document(uint64_t size = Arena::initialSize);
Document(_Value&& x, uint64_t size = Arena::initialSize);
Document(Document&& d) noexcept;

์ฃผ์š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ๋ฐ˜ํ™˜ ์„ค๋ช…
Get() _Value& ๋ฃจํŠธ ๊ฐ’ ์ ‘๊ทผ
Get() const const _Value& ๋ฃจํŠธ ๊ฐ’ ์ฝ๊ธฐ ์ „์šฉ ์ ‘๊ทผ
GetAllocator() Arena* ๋ฉ”๋ชจ๋ฆฌ ํ’€ ์ ‘๊ทผ

String

SSO(Small String Optimization)๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฌธ์ž์—ด ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson_string.h

ํŠน์ง•

  • Short String: 11๋ฐ”์ดํŠธ(CLAUJSON_STRING_BUF_SIZE) ์ดํ•˜๋Š” ์ธ๋ผ์ธ ๋ฒ„ํผ์— ์ €์žฅ (_ValueType::SHORT_STRING)
  • Long String: 11๋ฐ”์ดํŠธ ์ดˆ๊ณผ ์‹œ ํž™(๋˜๋Š” Arena)์— ํ• ๋‹น (_ValueType::STRING)
  • ๋ณต์‚ฌ ๋ถˆ๊ฐ€ (operator=(const String&) = delete)
  • ์ด๋™ ๊ฐ€๋Šฅ

์ฃผ์š” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
data() char* ํฌ์ธํ„ฐ ๋ฐ˜ํ™˜
size() ๋ฌธ์ž์—ด ๊ธธ์ด ๋ฐ˜ํ™˜
is_valid() ์œ ํšจ์„ฑ ํ™•์ธ
is_str() ๋ฌธ์ž์—ด ํƒ€์ž…์ธ์ง€ ํ™•์ธ
clear() ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ๋ฐ ์ดˆ๊ธฐํ™”
clone(Arena*) ๋ณต์‚ฌ๋ณธ ์ƒ์„ฑ
get_std_string(bool&) std::string์œผ๋กœ ๋ณ€ํ™˜
get_string_view(bool&) StringView๋กœ ๋ณ€ํ™˜
find(char, start) ๋ฌธ์ž ๊ฒ€์ƒ‰
substr(start, len) ๋ถ€๋ถ„ ๋ฌธ์ž์—ด ์ƒ์„ฑ
operator== / operator< ๋น„๊ต

Arena (๋ฉ”๋ชจ๋ฆฌ ํ’€)

๋ธ”๋ก ๊ธฐ๋ฐ˜ ๋ฉ”๋ชจ๋ฆฌ ํ’€๋กœ, ๋นˆ๋ฒˆํ•œ new/delete๋ฅผ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.

ํ—ค๋”: claujson_internal.h

ํŠน์ง•

  • ๋‘ ์ข…๋ฅ˜์˜ ๋ธ”๋ก ๊ด€๋ฆฌ: ์ผ๋ฐ˜ ํฌ๊ธฐ(no=0)์™€ ๋Œ€ํ˜• ํฌ๊ธฐ(no=1)
  • ์ •๋ ฌ(alignment) ์ง€์›: std::align์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ ์ •๋ ฌ ๋ณด์žฅ
  • link_from(): ์—ฌ๋Ÿฌ Arena๋ฅผ ํ•˜๋‚˜๋กœ ์—ฐ๊ฒฐ (๋ณ‘๋ ฌ ํŒŒ์‹ฑ ํ›„ ๋ณ‘ํ•ฉ ์‹œ ์‚ฌ์šฉ)

์ฃผ์š” ๋ฉ”์„œ๋“œ

template <class T>
T* allocate(uint64_t size, uint64_t align = alignof(T));

template <class T>
void deallocate(T* ptr, uint64_t len);   // ํ˜„์žฌ no-op (์ตœ์ ํ™” ๋ชฉ์  ์ฝ”๋“œ๋งŒ ์กด์žฌ)

template<typename T, typename... Args>
T* create(Args&&... args);               // allocate + placement new

void Clear();    // ๋ธ”๋ก ์žฌ์‚ฌ์šฉ (ํ•ด์ œํ•˜์ง€ ์•Š์Œ)
void Reset();    // ๋ธ”๋ก ๋ฆฌ์…‹
void link_from(Arena* other);  // ๋‹ค๋ฅธ Arena ๋ธ”๋ก์„ ์ด์ชฝ์œผ๋กœ ์—ฐ๊ฒฐ

์ƒ์ˆ˜

static const uint64_t initialSize = 1024 * 1024; // ๊ธฐ๋ณธ ๋ธ”๋ก ํฌ๊ธฐ (1MB)

ํŒŒ์„œ ๋ฐ ์ง๋ ฌํ™”

parser

JSON์„ ํŒŒ์‹ฑํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson.h

class parser {
    _simdjson::dom::parser_for_claujson test_;
    std::unique_ptr<ThreadPool> pool;
};

์ƒ์„ฑ์ž

parser(int thr_num = 0);  // thr_num=0์ด๋ฉด ํ•˜๋“œ์›จ์–ด ์Šค๋ ˆ๋“œ ์ˆ˜์—์„œ 2๋ฅผ ๋บ€ ๊ฐ’ ์‚ฌ์šฉ

ํŒŒ์‹ฑ ๋ฉ”์„œ๋“œ

// JSON ํŒŒ์ผ ํŒŒ์‹ฑ
std::pair<bool, uint64_t> parse(const std::string& fileName, Document& d, uint64_t thr_num);

// JSON ๋ฌธ์ž์—ด ํŒŒ์‹ฑ
std::pair<bool, uint64_t> parse_str(StringView str, Document& d, uint64_t thr_num);

// C++20: UTF-8 ๋ฌธ์ž์—ด ํŒŒ์‹ฑ
std::pair<bool, uint64_t> parse_str(std::u8string_view str, Document& d, uint64_t thr_num);

๋ฐ˜ํ™˜๊ฐ’: {์„ฑ๊ณต ์—ฌ๋ถ€, ์ฒ˜๋ฆฌ๋œ ํ† ํฐ ์ˆ˜}

ํŒŒ์‹ฑ ํŒŒ์ดํ”„๋ผ์ธ

1. simdjson stage1: ๊ตฌ์กฐ ํ† ํฐ ์ƒ‰์ธ ์ƒ์„ฑ
2. is_valid2(): ๋ณ‘๋ ฌ ๋ฌธ๋ฒ• ๊ฒ€์ฆ ๋ฐ count_vec ๊ตฌ์„ฑ
3. LoadData2::parse(): ๋ณ‘๋ ฌ JSON ํŠธ๋ฆฌ ๊ตฌ์„ฑ
   โ”œโ”€โ”€ ์ฒญํฌ๋ณ„ __LoadData() ๋ณ‘๋ ฌ ์‹คํ–‰ (ThreadPool)
   โ””โ”€โ”€ Merge(): ์ฒญํฌ ๊ฒฐ๊ณผ ์ˆœ์ฐจ ๋ณ‘ํ•ฉ
4. ์ตœ์ข… _Value ๋ฐ˜ํ™˜

writer

JSON์„ ์ง๋ ฌํ™”ํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

ํ—ค๋”: claujson.h

class writer {
    std::unique_ptr<ThreadPool> pool;
};

์ƒ์„ฑ์ž

writer(int thr_num = 0);

์ง๋ ฌํ™” ๋ฉ”์„œ๋“œ

๋ฉ”์„œ๋“œ ์„ค๋ช…
write_to_str(const _Value&, bool pretty) JSON ๋ฌธ์ž์—ด๋กœ ์ง๋ ฌํ™”
write_to_str2(const _Value&, bool pretty) JsonView ๋ฐฉ์‹์œผ๋กœ ์ง๋ ฌํ™” (์‹คํ—˜์ )
write(const string&, const _Value&, bool pretty) ํŒŒ์ผ๋กœ ์ง๋ ฌํ™”
write_parallel(Arena*, string&, _Value&, uint64_t, bool) ํŠธ๋ฆฌ ๋ถ„ํ•  ๋ณ‘๋ ฌ ์ง๋ ฌํ™”
write_parallel2(string&, const _Value&, uint64_t, bool) JsonView ๊ธฐ๋ฐ˜ ๋ณ‘๋ ฌ ์ง๋ ฌํ™”
write_parallel3(Arena*, string&, _Value&, uint64_t, bool) NodeView ๊ธฐ๋ฐ˜ ๋ณ‘๋ ฌ ์ง๋ ฌํ™” (์‹คํ—˜์ -ํ…Œ์ŠคํŠธ์ค‘..)

์ง๋ ฌํ™” ๋ฐฉ์‹ ๋น„๊ต

๋ฐฉ์‹ ํด๋ž˜์Šค ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํŠน์ง•
write_to_str LoadData2::_write No ์žฌ๊ท€์  DFS ์ˆœํšŒ
write_to_str2 JsonView + print ๊ฐ€๋Šฅ ๋ฐฐ์—ด ๊ธฐ๋ฐ˜ ์„ ํ˜• ์ˆœํšŒ
write_parallel LoadData2::write_ Yes ํŠธ๋ฆฌ ๋ถ„ํ•  ํ›„ ์ฒญํฌ๋ณ„ ์ง๋ ฌํ™”
write_parallel2 JsonView + print Yes ์„ ํ˜• JsonView ๋ฐฐ์—ด ๋ถ„ํ• 

์œ ํ‹ธ๋ฆฌํ‹ฐ

diff / patch

๋‘ JSON ๊ฐ’์˜ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

[[nodiscard]]
_Value diff(Arena* pool, const _Value& x, const _Value& y);

_Value& patch(Arena* pool, _Value& x, const _Value& diff);

diff ์ถœ๋ ฅ ํ˜•์‹

diff ๊ฒฐ๊ณผ๋Š” JSON Patch(RFC 6902 ์œ ์‚ฌ) ํ˜•์‹์˜ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค:

[
  { "op": "replace", "path": [...], "value": <new_value> },
  { "op": "remove",  "path": [...], "last_key": "key" },
  { "op": "remove",  "path": [...], "last_idx": 3 },
  { "op": "add",     "path": [...], "key": "key", "value": <value> },
  { "op": "add",     "path": [...], "value": <value> }
]

๋ฌธ์ž์—ด ๋ณ€ํ™˜ ํ•จ์ˆ˜

/*
// JSON ๋ฌธ์ž์—ด ๋‚ด ์ด์Šค์ผ€์ดํ”„ ์ฒ˜๋ฆฌ (์˜ˆ: \n -> \\n)
std::pair<bool, std::string> convert_to_string_in_json(StringView x);

// JSON ๋ฌธ์ž์—ด๋กœ์„œ ์œ ํšจํ•œ์ง€ ํ™•์ธ
bool is_valid_string_in_json(StringView x);

// ์ˆซ์ž ๋ฌธ์ž์—ด์„ _Value๋กœ ๋ณ€ํ™˜
bool convert_number(StringView x, claujson::_Value& data);

// ๋ฌธ์ž์—ด์„ _Value๋กœ ๋ณ€ํ™˜
bool convert_string(StringView x, claujson::_Value& data);
*/

C++20 (char8_t) ์ง€์›

/*
#if __cpp_lib_char8_t
std::pair<bool, std::string> convert_to_string_in_json(std::u8string_view x);
bool is_valid_string_in_json(std::u8string_view x);
#endif
*/

clean

void clean(_Value& x);

_Value์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. Arena๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์†Œ๋ฉธ์ž๋งŒ ํ˜ธ์ถœํ•˜๊ณ , ํž™ ํ• ๋‹น์˜ ๊ฒฝ์šฐ deleteํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ํ˜„์žฌ ๊ตฌํ˜„์—์„œ๋Š” ์ฆ‰์‹œ ๋ฐ˜ํ™˜(return)ํ•˜์—ฌ ์‹ค์ œ ํ•ด์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Arena์˜ ์ƒ๋ช…์ฃผ๊ธฐ์— ๋”ฐ๋ผ ์ผ๊ด„ ํ•ด์ œ๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š” ์„ค๊ณ„์ž…๋‹ˆ๋‹ค.


Log ์‹œ์Šคํ…œ

claujson::Log log;          // ์ „์—ญ ๋กœ๊ทธ ๊ฐ์ฒด
claujson::Log::Info info;   // ์ •๋ณด ๋ ˆ๋ฒจ ํƒœ๊ทธ
claujson::Log::Warning warn; // ๊ฒฝ๊ณ  ๋ ˆ๋ฒจ ํƒœ๊ทธ

์‚ฌ์šฉ ์˜ˆ์‹œ

claujson::log.console();        // ์ฝ˜์†” ์ถœ๋ ฅ ํ™œ์„ฑํ™”
claujson::log.info();           // INFO ๋ ˆ๋ฒจ ํ™œ์„ฑํ™”
claujson::log.warn();           // WARN ๋ ˆ๋ฒจ ํ™œ์„ฑํ™”

claujson::log << claujson::info << "ํŒŒ์‹ฑ ์‹œ์ž‘\n";
claujson::log << claujson::warn << "์˜ค๋ฅ˜ ๋ฐœ์ƒ\n";

์ถœ๋ ฅ ์˜ต์…˜

์˜ต์…˜ ์„ค๋ช…
log.console() ์ฝ˜์†” ์ถœ๋ ฅ
log.file() ํŒŒ์ผ ์ถœ๋ ฅ
log.console_and_file() ์ฝ˜์†” + ํŒŒ์ผ
log.no_print() ์ถœ๋ ฅ ๋น„ํ™œ์„ฑํ™”
log.file_name(str) ๋กœ๊ทธ ํŒŒ์ผ๋ช… ์„ค์ •

ํƒ€์ž… ์‹œ์Šคํ…œ

_ValueType ์—ด๊ฑฐํ˜•

enum class _ValueType : int32_t {
    NONE = 0,        // ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ์ƒํƒœ
    ARRAY,           // JSON ๋ฐฐ์—ด
    OBJECT,          // JSON ๊ฐ์ฒด
    PARTIAL_JSON,    // ๋ถ€๋ถ„ JSON (๋‚ด๋ถ€์šฉ)
    INT,             // 64๋น„ํŠธ ๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜
    UINT,            // 64๋น„ํŠธ ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜
    FLOAT,           // IEEE 754 double
    BOOL,            // ๋ถˆ๋ฆฌ์–ธ
    NULL_,           // JSON null
    STRING,          // ๋ฌธ์ž์—ด (ํž™/Arena ํ• ๋‹น)
    SHORT_STRING,    // ๋ฌธ์ž์—ด (11๋ฐ”์ดํŠธ ์ดํ•˜ ์ธ๋ผ์ธ ์ €์žฅ)
    NOT_VALID,       // ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฐ’ (์ ‘๊ทผ ๋ถˆ๊ฐ€ ๋งˆ์ปค)
    ERROR            // ์˜ค๋ฅ˜ ์ƒํƒœ
};

Value ๋ž˜ํผ ํด๋ž˜์Šค

_Value๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๋ž˜ํผ์ž…๋‹ˆ๋‹ค.

class Value {
    _Value x;
public:
    Value(_Value&& x) noexcept;
    Value(Value&& x) noexcept;
    _Value& Get() noexcept;
    const _Value& Get() const noexcept;
};

add_element, add_object_element ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋Š” Value๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ์†Œ์œ ๊ถŒ์„ ์ด์ „ํ•ฉ๋‹ˆ๋‹ค.


๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

Arena ๊ธฐ๋ฐ˜ ํ• ๋‹น

Arena pool;

// Array ์ƒ์„ฑ - pool ํ• ๋‹น
_Value arr = Array::Make(&pool);

// Object ์ƒ์„ฑ - pool ํ• ๋‹น
_Value obj = Object::Make(&pool);

// ๋ฌธ์ž์—ด ์ƒ์„ฑ - pool ํ• ๋‹น
_Value str(&pool, "hello"sv);

ํ• ๋‹น ์ „๋žต

ํฌ๊ธฐ < defaultBlockSize(1MB) โ†’ Block[0] (์ผ๋ฐ˜ ๋ธ”๋ก)
ํฌ๊ธฐ >= defaultBlockSize    โ†’ Block[1] (๋Œ€ํ˜• ๋ธ”๋ก)

๋ณ‘๋ ฌ ํŒŒ์‹ฑ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณ‘ํ•ฉ

๋ฉ”์ธ pool
  โ””โ”€โ”€ link_from(sub_pool_1)
  โ””โ”€โ”€ link_from(sub_pool_2)
  โ””โ”€โ”€ link_from(sub_pool_3)

๊ฐ ์Šค๋ ˆ๋“œ๋Š” ๋…๋ฆฝ์ ์ธ Arena๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์‹ฑํ•˜๊ณ , ์™„๋ฃŒ ํ›„ ๋ฉ”์ธ Arena์— ๋ธ”๋ก์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์Šค๋ ˆ๋“œ ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ๊ฒฝํ•ฉ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.


์‚ฌ์šฉ ์˜ˆ์‹œ

๊ธฐ๋ณธ ํŒŒ์‹ฑ

#include "claujson.h"

// ๋กœ๊ทธ ์„ค์ • (์„ ํƒ)
claujson::log.console();
claujson::log.warn();

// ํŒŒ์„œ ์ƒ์„ฑ
claujson::parser p;
claujson::Document doc;

// ํŒŒ์ผ ํŒŒ์‹ฑ
auto [ok, token_count] = p.parse("data.json", doc, 4);
if (!ok) {
    // ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
    return;
}

claujson::_Value& root = doc.Get();

๋ฌธ์ž์—ด ํŒŒ์‹ฑ

claujson::parser p;
claujson::Document doc;

auto [ok, _] = p.parse_str(R"({"name": "Alice", "age": 30})", doc, 1);
if (ok) {
    auto& root = doc.Get();
    // root๋Š” Object
}

๊ฐ’ ์ ‘๊ทผ

claujson::_Value& root = doc.Get();

// ๊ฐ์ฒด ์ ‘๊ทผ
if (root.is_object()) {
    claujson::Arena arena;
    claujson::_Value key(&arena, "name");
    
    claujson::_Value& name = root[key];
    if (name.is_str()) {
        bool fail = false;
        std::string s = name.str_val().get_std_string(fail);
    }
}

// ๋ฐฐ์—ด ์ ‘๊ทผ
if (root.is_array()) {
    uint64_t sz = root.as_array()->size();
    for (uint64_t i = 0; i < sz; ++i) {
        claujson::_Value& elem = root[i];
        if (elem.is_int()) {
            int64_t v = elem.int_val();
        }
    }
}

๊ฐ’ ์ƒ์„ฑ ๋ฐ ์กฐ์ž‘

claujson::Arena pool;

// ๋ฐฐ์—ด ์ƒ์„ฑ
claujson::_Value arr = claujson::Array::Make(&pool);
arr.as_array()->add_element(claujson::Value(claujson::_Value(42LL)));
arr.as_array()->add_element(claujson::Value(claujson::_Value(true)));
arr.as_array()->add_element(claujson::Value(claujson::_Value(&pool, "hello"sv)));

// ๊ฐ์ฒด ์ƒ์„ฑ
claujson::_Value obj = claujson::Object::Make(&pool);
obj.as_object()->add_element(
    claujson::Value(claujson::_Value(&pool, "key"sv)),
    claujson::Value(claujson::_Value(123LL))
);

JSON ์ง๋ ฌํ™”

claujson::writer w;

// ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
std::string json_str = w.write_to_str(root, false);       // compact
std::string json_pretty = w.write_to_str(root, true);     // pretty

// ํŒŒ์ผ๋กœ ์ €์žฅ
w.write("output.json", root, false);

// ๋ณ‘๋ ฌ ์ง๋ ฌํ™” (๋Œ€์šฉ๋Ÿ‰)
Arena* pool = doc.GetAllocator();
w.write_parallel(pool, "output.json", root, 4, false);

diff / patch

claujson::Arena pool;
claujson::_Value d = claujson::diff(&pool, original, modified);

// diff ์ ์šฉ
claujson::_Value& patched = claujson::patch(&pool, original, d);

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ƒ์„ธ

Pointer ํด๋ž˜์Šค

ํฌ์ธํ„ฐ์— 2๋น„ํŠธ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค (ํฌ์ธํ„ฐ ํƒœ๊น… ๊ธฐ๋ฒ•).

class Pointer {
    void* ptr;
    // bit 63     : left_type  (is_virtual ์—ฌ๋ถ€)
    // bits 1-0   : right_type (1=Array, 2=Object, 3=PartialJson)
};

Array์™€ Object์˜ parent ํ•„๋“œ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

my_vector<T> (Vector2<T>)

Arena๋ฅผ ์ง€์›ํ•˜๋Š” ์ปค์Šคํ…€ ๋™์  ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.

template <class T>
using my_vector = Vector2<T>;

์ฃผ์š” ๊ธฐ๋Šฅ:

  • Arena ํ• ๋‹น/ํ•ด์ œ ์ง€์›
  • Divide(start_idx): ์ง€์ • ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ๋๊นŒ์ง€ ๋ถ„๋ฆฌํ•˜์—ฌ ์ƒˆ ๋ฒกํ„ฐ ๋ฐ˜ํ™˜
  • insert(start, end): ์ด๋™ ์‹œ๋งจํ‹ฑ์œผ๋กœ ์›์†Œ ์‚ฝ์ž…

LoadData2 ๋‚ด๋ถ€ ํด๋ž˜์Šค

๋ณ‘๋ ฌ ํŒŒ์‹ฑ ๋ฐ ์ง๋ ฌํ™”์˜ ํ•ต์‹ฌ ๋กœ์ง์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ:

๋ฉ”์„œ๋“œ ์„ค๋ช…
__LoadData(...) ์ •์  ํ•จ์ˆ˜. ๋‹จ์ผ ์ฒญํฌ๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ PartialJson ๊ตฌ์„ฑ
Merge(next, ut, ut_next) ๋‘ PartialJson์„ ๋ณ‘ํ•ฉ
Merge2(next, ut, ut_next, op) Merge์˜ ๋ณ€ํ˜• (null ut ์ฒ˜๋ฆฌ ์ถ”๊ฐ€)
Divide(pool, pos, result) ํŠธ๋ฆฌ์˜ ํŠน์ • ์œ„์น˜์—์„œ ๋ถ„ํ• ํ•˜์—ฌ PartialJson ์ƒ์„ฑ
Divide2(pool, n, j, result, hint) n๊ฐœ์˜ ๋ถ„ํ• ์  ๊ณ„์‚ฐ ๋ฐ ๋ถ„ํ•  ์‹คํ–‰
Find2(root, n, idx, ...) ๊ท ๋“ฑ ๋ถ„ํ• ์  ํƒ์ƒ‰ (์žฌ๊ท€)
Size(Array*) ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋…ธ๋“œ ์ˆ˜ ๊ณ„์‚ฐ
Size2(const _Value&) JsonView์šฉ ๋…ธ๋“œ ์ˆ˜ ๊ณ„์‚ฐ
_write(...) ์žฌ๊ท€ DFS ์ง๋ ฌํ™”
_write2(...) ๋ฐ˜๋ณต ์Šคํƒ ๊ธฐ๋ฐ˜ ์ง๋ ฌํ™”

is_valid2 ํ•จ์ˆ˜

simdjson์˜ ๊ตฌ์กฐ ํ† ํฐ ๋ฐฐ์—ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ JSON ๋ฌธ๋ฒ• ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. goto ๊ธฐ๋ฐ˜ ์ƒํƒœ ๋จธ์‹ ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒํƒœ ๋ชฉ๋ก:

  • object_begin / object_field / object_continue
  • array_begin / array_value / array_continue
  • scope_end / document_end

๋™์‹œ์— ๊ฐ ๋ฐฐ์—ด/๊ฐ์ฒด์˜ ์›์†Œ ์ˆ˜๋ฅผ count_vec์— ๊ธฐ๋กํ•˜์—ฌ ์ดํ›„ reserve_data_list() ์ตœ์ ํ™”์— ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

JsonView ๋ฐฐ์—ด

write_parallel2 / write_to_str2์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์„ ํ˜• ๋ทฐ ํ‘œํ˜„์ž…๋‹ˆ๋‹ค.

struct JsonView {
    Pointer value;
    // right_type: 0=ARRAY_START, 1=OBJECT_START, 2=KEY, 3=VALUE
    // left_type:  1 = END(ARRAY/OBJECT)
};

JSON ํŠธ๋ฆฌ๋ฅผ DFS ์ˆœ์„œ๋กœ ํŽผ์ณ ๋ฐฐ์—ด์— ์ €์žฅํ•œ ๋’ค, ์›ํ•˜๋Š” ๊ตฌ๊ฐ„์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์— ๋ถ„๋ฐฐํ•˜์—ฌ ๋ณ‘๋ ฌ ์ง๋ ฌํ™”๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.


๋ณธ ๋ฌธ์„œ๋Š” claujson ์†Œ์Šค ์ฝ”๋“œ ๋ถ„์„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors