-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(json): Adds a reference counted string class #6497
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
Conversation
1b99cf1 to
1b96eec
Compare
2f0dad8 to
3269461
Compare
3269461 to
9b3c115
Compare
🤖 Augment PR SummarySummary: Introduces a new reference-counted string wrapper to support JSON key/value lifetimes on top of the existing interned-blob representation. Changes:
Technical Notes: The PR explicitly does not wire 🤖 Was this summary useful? React with 👍 or 👎 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9b3c115 to
7cd8f4d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces InternedString, a reference-counted string class that wraps the InternedBlobHandle from PR #6456. The class manages string interning and reference counting for JSON keys, providing a memory-efficient way to store duplicate strings by maintaining a thread-local pool of unique string blobs. The implementation includes lifecycle management, string API compatibility with jsoncons, and comprehensive test coverage.
Changes:
- Introduces
InternedStringclass that manages reference counting and lifetimes for interned string blobs - Enhances
InternedBlobHandlewith comparison operators and explicit bool conversion for null checks - Removes the raw
SetRefCount()method to enforce proper reference count management through the public API - Updates tests to use the new API and adds comprehensive tests for
InternedStringfunctionality
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/core/json/detail/interned_string.h | Defines the InternedString class with RAII semantics for reference-counted string interning, including constructors required by jsoncons |
| src/core/json/detail/interned_string.cc | Implements reference counting logic (Acquire/Release), string interning with deduplication, and thread-local pool management |
| src/core/json/detail/interned_blob.h | Adds comparison operators and explicit bool conversion; removes SetRefCount to enforce encapsulation |
| src/core/json/detail/interned_blob.cc | Updates blob creation and accessors to handle empty strings/null pointers; removes SetRefCount implementation |
| src/core/json/interned_blob_test.cc | Updates existing tests to use IncrRefCount instead of removed SetRefCount; adds comprehensive tests for InternedString including pool behavior, string API, and constructor edge cases |
| src/core/json/CMakeLists.txt | Adds interned_string.cc to the build configuration |
src/core/json/detail/interned_blob.h
Outdated
| [[nodiscard]] static InternedBlobHandle Create(std::string_view sv); | ||
|
|
||
| uint32_t RefCount() const; | ||
| [[nodiscard]] uint32_t Size() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not see value in adding [[nodiscard]] to all the accessors. the only function that matters imho is Create as it can potentially cause a leak
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
| } | ||
|
|
||
| int InternedString::compare(const InternedString& other) const { | ||
| return std::string_view{*this}.compare(other); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move one-liners to header files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved
| @@ -0,0 +1,78 @@ | |||
| // Copyright 2025, DragonflyDB authors. All rights reserved. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, please change the date to 2026 in all the touched files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
romange
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
dranikpg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine from a design perspective
I missed signature in a commit. Will have to rebase |
A null blob is now allowed. The reason is that sometimes jsoncons will create an empty string. We want to allow for empty strings without carrying the "" and its metadata around, and without adding "" to the pool. For this reason a null blob and associated handle is allowed. It provides short circuited accessors, but refcount on such a blob is a programming error. In addition comparison operators are added to be able to compare the InternedString objects trivially. Signed-off-by: Abhijat Malviya <[email protected]>
Signed-off-by: Abhijat Malviya <[email protected]>
The string class wraps the previously added blob class. It decides at creation time whether to create a new blob, or bump up the refcount of an existing blob in the pool. The pool is thread local, and is used by the strings on that thread to store pointers to allocated blobs. When a string is destroyed it decrements the ref-count, dropping the blob if necessary (ie refcount == 0). A lot of boilerplate in this class is from trial and error, adding methods that jsoncons required to be able to use this class as a key. Signed-off-by: Abhijat Malviya <[email protected]>
Signed-off-by: Abhijat Malviya <[email protected]>
Signed-off-by: Abhijat Malviya <[email protected]>
Signed-off-by: Abhijat Malviya <[email protected]>
95793e5 to
99cf817
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
| InternedBlobHandle::operator std::string_view() const { | ||
| DCHECK(blob_) << "Attempt to convert empty blob to string_view"; | ||
| return {blob_, Size()}; | ||
| return blob_ ? std::string_view{blob_, Size()} : ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i could be in header file.
The code is not hooked into jsoncons yet, it will be done in a small, final PR, kept separate because a lot of tests have to be adjusted at that point.