Skip to content

Commit

Permalink
Add a separate property, isCacheable, to SharedKeys.
Browse files Browse the repository at this point in the history
If cacheable, Dict::get(key &keyToFind) will cache the string key to integer key and enhance the performance of the ensuing gets. This is good if the doucment is not changed.

For PersistentSharedKey, the library manages the property: it is cacheable only if it is not in a transaction when Dict::get is called.

For SharedKeys, the client manages it. If it anticipates the sharedKeys may outlive the underlying document changes, it should call SharedKeys::disableCaching().
  • Loading branch information
jianminzhao committed Nov 18, 2023
1 parent e5115d3 commit 8499ba2
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 5 deletions.
1 change: 1 addition & 0 deletions API/fleece/Expert.hh
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ namespace fleece {
inline void writeState(const Encoder &enc);
unsigned count() const {return FLSharedKeys_Count(_sk);}
void revertToCount(unsigned count) {FLSharedKeys_RevertToCount(_sk, count);}
void disableCaching() {if (_sk) FLSharedKeys_DisableCaching(_sk);}

operator FLSharedKeys FL_NULLABLE () const {return _sk;}
bool operator== (SharedKeys other) const {return _sk == other._sk;}
Expand Down
3 changes: 3 additions & 0 deletions API/fleece/FLExpert.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ extern "C" {
/** Reverts an FLSharedKeys by "forgetting" any keys added since it had the count `oldCount`. */
FLEECE_PUBLIC void FLSharedKeys_RevertToCount(FLSharedKeys, unsigned oldCount) FLAPI;

/** Disable caching of the SharedKeys.. */
FLEECE_PUBLIC void FLSharedKeys_DisableCaching(FLSharedKeys) FLAPI;

/** Increments the reference count of an FLSharedKeys. */
FLEECE_PUBLIC FLSharedKeys FL_NULLABLE FLSharedKeys_Retain(FLSharedKeys FL_NULLABLE) FLAPI;

Expand Down
4 changes: 2 additions & 2 deletions Fleece.xcodeproj/xcshareddata/xcschemes/Fleece Test.xcscheme
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1320"
version = "1.3">
version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
Expand Down Expand Up @@ -31,7 +31,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Test_CE"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableAddressSanitizer = "YES"
Expand Down
1 change: 1 addition & 0 deletions Fleece/API_Impl/Fleece.cc
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ bool FLSharedKeys_LoadState(FLSharedKeys sk, FLValue s) FLAPI {return sk->loa
FLSliceResult FLSharedKeys_GetStateData(FLSharedKeys sk) FLAPI {return toSliceResult(sk->stateData());}
FLString FLSharedKeys_Decode(FLSharedKeys sk, int key) FLAPI {return sk->decode(key);}
void FLSharedKeys_RevertToCount(FLSharedKeys sk, unsigned c) FLAPI {sk->revertToCount(c);}
void FLSharedKeys_DisableCaching(FLSharedKeys sk) FLAPI { sk->disableCaching(); }

FLSharedKeys FLSharedKeys_NewWithRead(FLSharedKeysReadCallback callback, void* FL_NULLABLE context) FLAPI {
return retain(new FLPersistentSharedKeys(callback, context));
Expand Down
2 changes: 1 addition & 1 deletion Fleece/Core/Dict.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ namespace fleece { namespace impl {
// shared key, because the transaction might be rolled back. If the found
// shared key is rolled back as part of rolling back the transaction, continuing
// to use it would lead to incorrect lookup results.
keyToFind._hasNumericKey = !sharedKeys->isInTransaction();
keyToFind._hasNumericKey = sharedKeys->isCacheable();
return get(keyToFind._numericKey);
}
}
Expand Down
2 changes: 2 additions & 0 deletions Fleece/Core/Dict.hh
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ namespace fleece { namespace impl {
slice string() const noexcept {return _rawString;}
int compare(const key &k) const noexcept {return _rawString.compare(k._rawString);}
key(const key&) =delete;
#ifndef LITECORE_CPPTEST
private:
#endif
void setSharedKeys(SharedKeys*);

slice const _rawString;
Expand Down
2 changes: 2 additions & 0 deletions Fleece/Core/SharedKeys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ namespace fleece { namespace impl {
LOCK(_refreshMutex);
throwIf(_inTransaction, SharedKeysStateError, "already in transaction");
_inTransaction = true;
disableCaching();
read(); // Catch up with any external changes
}

Expand All @@ -260,6 +261,7 @@ namespace fleece { namespace impl {
if (_inTransaction) {
_committedPersistedCount = _persistedCount;
_inTransaction = false;
enableCaching();
}
}

Expand Down
8 changes: 6 additions & 2 deletions Fleece/Core/SharedKeys.hh
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ namespace fleece { namespace impl {

bool isUnknownKey(int key) const FLPURE;

bool isInTransaction() const FLPURE {return _inTransaction;}

virtual bool refresh() {return false;}

static const size_t kMaxCount = 2048; // Max number of keys to store
Expand All @@ -124,7 +122,12 @@ namespace fleece { namespace impl {
void setPlatformStringForKey(int key, PlatformString) const;
PlatformString platformStringForKey(int key) const;

bool isCacheable() const FLPURE { return _isCacheable; }
void disableCaching() { _isCacheable = false; }

protected:
void enableCaching() { _isCacheable = true; }

virtual ~SharedKeys();

/** Determines whether a new string should be added. Default implementation returns true
Expand All @@ -143,6 +146,7 @@ namespace fleece { namespace impl {
mutable std::mutex _mutex;
unsigned _count {0};
bool _inTransaction {true}; // (for PersistentSharedKeys)
bool _isCacheable {true}; // SharedKeys are cacheable unless explicitly disabled.
mutable std::vector<PlatformString> _platformStringsByKey; // Reverse mapping, int->platform key
ConcurrentMap _table; // Hash table mapping slice->int
std::array<slice, kMaxCount> _byKey; // Reverse mapping, int->slice
Expand Down
19 changes: 19 additions & 0 deletions Tests/SharedKeysTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,11 @@ TEST_CASE("encoding", "[SharedKeys]") {
Dict::key typeKey("type"_sl), attsKey("_attachments"_sl);

const Value *v = root->get(typeKey);
CHECK(typeKey._hasNumericKey);
REQUIRE(v);
REQUIRE(v->asString() == "animal"_sl);
const Dict *atts = root->get(attsKey)->asDict();
CHECK(attsKey._hasNumericKey);
REQUIRE(atts);
REQUIRE(atts->get("thumbnail.jpg"_sl) != nullptr);
REQUIRE(atts->get(typeKey) != nullptr);
Expand All @@ -442,6 +444,23 @@ TEST_CASE("encoding", "[SharedKeys]") {
Dict::key thumbKey("thumbnail.jpg"_sl);
REQUIRE(atts->get(thumbKey) != nullptr);
}
SECTION("Dict::key Not Cache") {
sk->disableCaching();

// Use a Dict::key:
Dict::key typeKey("type"_sl), attsKey("_attachments"_sl);
CHECK(!typeKey._hasNumericKey);
const Value *v = root->get(typeKey);
REQUIRE(v);
REQUIRE(v->asString() == "animal"_sl);

const Dict *atts = root->get(attsKey)->asDict();
CHECK(!attsKey._hasNumericKey);
REQUIRE(atts);
REQUIRE(atts->get("thumbnail.jpg"_sl) != nullptr);
REQUIRE(atts->get(typeKey) != nullptr);
REQUIRE(atts->get(attsKey) == nullptr);
}
SECTION("Path lookup") {
Path attsTypePath("_attachments.type");
const Value *t = attsTypePath.eval(root);
Expand Down
3 changes: 3 additions & 0 deletions Xcode/xcconfigs/Project_Debug.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ GCC_OPTIMIZATION_LEVEL = 0
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1
ENABLE_TESTABILITY = YES
MTL_ENABLE_DEBUG_INFO = YES

GCC_PREPROCESSOR_DEFINITIONS[config=Test_EE] = $(GCC_PREPROCESSOR_DEFINITIONS) LITECORE_CPPTEST
GCC_PREPROCESSOR_DEFINITIONS[config=Test_CE] = $(GCC_PREPROCESSOR_DEFINITIONS) LITECORE_CPPTEST

0 comments on commit 8499ba2

Please sign in to comment.