Skip to content
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

Add a separate property, isCacheable, to SharedKeys. #195

Merged
merged 2 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
1 change: 1 addition & 0 deletions Fleece/Core/Dict.hh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ 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;
bool isShared() const noexcept {return _hasNumericKey;}
private:
void setSharedKeys(SharedKeys*);

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.isShared());
REQUIRE(v);
REQUIRE(v->asString() == "animal"_sl);
const Dict *atts = root->get(attsKey)->asDict();
CHECK(attsKey.isShared());
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.isShared());
const Value *v = root->get(typeKey);
REQUIRE(v);
REQUIRE(v->asString() == "animal"_sl);

const Dict *atts = root->get(attsKey)->asDict();
CHECK(!attsKey.isShared());
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
2 changes: 1 addition & 1 deletion Tests/ValueTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ namespace fleece {

caughtException = false;
// ++iter will throw if already at the end.
// OutOfRange exception should contain the backtrace.
// OutOfRange exception should not contain the backtrace.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake. Should be "... not contain the backtrace."

try {
++iter;
} catch (const FleeceException& exc) {
Expand Down
Loading