-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Abstract a class named ObjectCache and implement StoragePageCache usi…
…ng ObjectCache. Signed-off-by: trueeyu <lxhhust350@qq.com>
- Loading branch information
Showing
21 changed files
with
1,177 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright 2021-present StarRocks, Inc. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include "cache/object_cache/cache_types.h" | ||
#include "common/status.h" | ||
#include "util/slice.h" | ||
|
||
namespace starrocks { | ||
|
||
class ObjectCacheModule { | ||
public: | ||
virtual ~ObjectCacheModule() = default; | ||
|
||
virtual Status init() = 0; | ||
|
||
virtual Status insert(const std::string& key, void* value, size_t size, size_t charge, ObjectCacheDeleter deleter, | ||
ObjectCacheHandlePtr* handle, ObjectCacheWriteOptions* options) = 0; | ||
|
||
virtual Status lookup(const std::string& key, ObjectCacheHandlePtr* handle, ObjectCacheReadOptions* options) = 0; | ||
|
||
virtual Status remove(const std::string& key) = 0; | ||
|
||
virtual void release(ObjectCacheHandlePtr handle) = 0; | ||
|
||
virtual const void* value(ObjectCacheHandlePtr handle) = 0; | ||
|
||
virtual Slice value_slice(ObjectCacheHandlePtr handle) = 0; | ||
|
||
virtual Status adjust_capacity(int64_t delta, size_t min_capacity) = 0; | ||
|
||
virtual Status set_capacity(size_t capacity) = 0; | ||
|
||
virtual size_t capacity() const = 0; | ||
|
||
virtual size_t usage() const = 0; | ||
|
||
virtual size_t lookup_count() const = 0; | ||
|
||
virtual size_t hit_count() const = 0; | ||
|
||
virtual const ObjectCacheMetrics metrics() const = 0; | ||
|
||
virtual Status prune() = 0; | ||
|
||
virtual Status shutdown() = 0; | ||
}; | ||
|
||
} // namespace starrocks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright 2021-present StarRocks, Inc. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include <functional> | ||
#include <ostream> | ||
#include <string> | ||
|
||
// Not a good way to import lru cache header here, just for temporary compatibility with old deleters. | ||
#include "util/lru_cache.h" | ||
|
||
namespace starrocks { | ||
|
||
enum class ObjectCacheModuleType { LRUCACHE, STARCACHE }; | ||
|
||
struct ObjectCacheOptions { | ||
size_t capacity = 0; | ||
ObjectCacheModuleType module = ObjectCacheModuleType::LRUCACHE; | ||
}; | ||
|
||
struct ObjectCacheWriteOptions { | ||
// The priority of the cache object, only support 0 and 1 now. | ||
int8_t priority = 0; | ||
// If ttl_seconds=0 (default), no ttl restriction will be set. If an old one exists, remove it. | ||
uint64_t ttl_seconds = 0; | ||
// If overwrite=true, the cache value will be replaced if it already exists. | ||
bool overwrite = false; | ||
// The probability to evict other items if the cache space is full, which can help avoid frequent cache replacement | ||
// and improve cache hit rate sometimes. | ||
// It is expressed as a percentage. If evict_probability is 10, it means the probability to evict other data is 10%. | ||
int32_t evict_probability = 100; | ||
}; | ||
|
||
struct ObjectCacheReadOptions {}; | ||
|
||
struct ObjectCacheHandle {}; | ||
|
||
struct ObjectCacheMetrics { | ||
size_t capacity = 0; | ||
size_t usage = 0; | ||
size_t lookup_count = 0; | ||
size_t hit_count = 0; | ||
size_t object_item_count = 0; | ||
}; | ||
|
||
using ObjectCacheHandlePtr = ObjectCacheHandle*; | ||
|
||
// using CacheDeleter = std::function<void(const std::string&, void*)>; | ||
// | ||
// We only use the deleter function of the lru cache temporarily. | ||
// Maybe a std::function object or a function pointer like `void (*)(std::string&, void*)` which | ||
// independent on lru cache is more appropriate, but it is not easy to convert them to the lru | ||
// cache deleter when using a lru cache module. | ||
using ObjectCacheDeleter = void (*)(const CacheKey&, void*); | ||
|
||
inline std::ostream& operator<<(std::ostream& os, const ObjectCacheModuleType& module) { | ||
switch (module) { | ||
case ObjectCacheModuleType::LRUCACHE: | ||
os << "lrucache"; | ||
break; | ||
case ObjectCacheModuleType::STARCACHE: | ||
os << "starcache"; | ||
break; | ||
} | ||
return os; | ||
} | ||
|
||
} // namespace starrocks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// Copyright 2021-present StarRocks, Inc. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "cache/object_cache/lrucache_module.h" | ||
|
||
#include <butil/fast_rand.h> | ||
|
||
#include "cache/status.h" | ||
#include "common/logging.h" | ||
|
||
namespace starrocks { | ||
|
||
LRUCacheModule::~LRUCacheModule() { | ||
if (!_cache) { | ||
_cache->prune(); | ||
} | ||
} | ||
|
||
Status LRUCacheModule::init() { | ||
if (!_cache) { | ||
_cache.reset(new_lru_cache(_options.capacity)); | ||
} | ||
return Status::OK(); | ||
} | ||
|
||
Status LRUCacheModule::insert(const std::string& key, void* value, size_t size, size_t charge, | ||
ObjectCacheDeleter deleter, ObjectCacheHandlePtr* handle, | ||
ObjectCacheWriteOptions* options) { | ||
if (!_check_write(charge, options)) { | ||
return Status::InternalError("cache insertion is rejected"); | ||
} | ||
auto* lru_handle = _cache->insert(key, value, charge, size, deleter, static_cast<CachePriority>(options->priority)); | ||
if (handle) { | ||
*handle = reinterpret_cast<ObjectCacheHandlePtr>(lru_handle); | ||
} | ||
return Status::OK(); | ||
} | ||
|
||
Status LRUCacheModule::lookup(const std::string& key, ObjectCacheHandlePtr* handle, ObjectCacheReadOptions* options) { | ||
auto* lru_handle = _cache->lookup(CacheKey(key)); | ||
if (!lru_handle) { | ||
return Status::NotFound("no such entry"); | ||
} | ||
*handle = reinterpret_cast<ObjectCacheHandlePtr>(lru_handle); | ||
return Status::OK(); | ||
} | ||
|
||
Status LRUCacheModule::remove(const std::string& key) { | ||
_cache->erase(CacheKey(key)); | ||
return Status::OK(); | ||
} | ||
|
||
void LRUCacheModule::release(ObjectCacheHandlePtr handle) { | ||
auto lru_handle = reinterpret_cast<Cache::Handle*>(handle); | ||
_cache->release(lru_handle); | ||
} | ||
|
||
const void* LRUCacheModule::value(ObjectCacheHandlePtr handle) { | ||
auto lru_handle = reinterpret_cast<Cache::Handle*>(handle); | ||
return _cache->value(lru_handle); | ||
} | ||
|
||
Slice LRUCacheModule::value_slice(ObjectCacheHandlePtr handle) { | ||
auto lru_handle = reinterpret_cast<Cache::Handle*>(handle); | ||
return _cache->value_slice(lru_handle); | ||
} | ||
|
||
Status LRUCacheModule::adjust_capacity(int64_t delta, size_t min_capacity) { | ||
if (_cache->adjust_capacity(delta, min_capacity)) { | ||
return Status::OK(); | ||
} | ||
return Status::InternalError("adjust quota failed"); | ||
} | ||
|
||
Status LRUCacheModule::set_capacity(size_t capacity) { | ||
_cache->set_capacity(capacity); | ||
return Status::OK(); | ||
} | ||
|
||
size_t LRUCacheModule::capacity() const { | ||
return _cache->get_capacity(); | ||
} | ||
|
||
size_t LRUCacheModule::usage() const { | ||
return _cache->get_memory_usage(); | ||
} | ||
|
||
size_t LRUCacheModule::lookup_count() const { | ||
return _cache->get_lookup_count(); | ||
} | ||
|
||
size_t LRUCacheModule::hit_count() const { | ||
return _cache->get_hit_count(); | ||
} | ||
|
||
const ObjectCacheMetrics LRUCacheModule::metrics() const { | ||
ObjectCacheMetrics m; | ||
m.capacity = _cache->get_capacity(); | ||
m.usage = _cache->get_memory_usage(); | ||
m.lookup_count = _cache->get_lookup_count(); | ||
m.hit_count = _cache->get_hit_count(); | ||
// Unsupported | ||
m.object_item_count = 0; | ||
return m; | ||
} | ||
|
||
Status LRUCacheModule::prune() { | ||
_cache->prune(); | ||
return Status::OK(); | ||
} | ||
|
||
Status LRUCacheModule::shutdown() { | ||
_cache->prune(); | ||
return Status::OK(); | ||
} | ||
|
||
bool LRUCacheModule::_check_write(size_t charge, ObjectCacheWriteOptions* options) const { | ||
if (options->evict_probability >= 100) { | ||
return true; | ||
} | ||
if (options->evict_probability <= 0) { | ||
return false; | ||
} | ||
|
||
// TODO: The cost of this call may be relatively high, and it needs to be optimized later. | ||
if (_cache->get_memory_usage() + charge <= _cache->get_capacity()) { | ||
return true; | ||
} | ||
|
||
if (butil::fast_rand_less_than(100) < options->evict_probability) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} // namespace starrocks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright 2021-present StarRocks, Inc. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include "cache/object_cache/cache_module.h" | ||
#include "util/lru_cache.h" | ||
|
||
namespace starrocks { | ||
|
||
class Cache; | ||
|
||
class LRUCacheModule : public ObjectCacheModule { | ||
public: | ||
LRUCacheModule(const ObjectCacheOptions& options) : _options(options) {} | ||
|
||
~LRUCacheModule(); | ||
|
||
Status init() override; | ||
|
||
Status insert(const std::string& key, void* value, size_t size, size_t charge, ObjectCacheDeleter deleter, | ||
ObjectCacheHandlePtr* handle, ObjectCacheWriteOptions* options) override; | ||
|
||
Status lookup(const std::string& key, ObjectCacheHandlePtr* handle, ObjectCacheReadOptions* options) override; | ||
|
||
Status remove(const std::string& key) override; | ||
|
||
void release(ObjectCacheHandlePtr handle) override; | ||
|
||
const void* value(ObjectCacheHandlePtr handle) override; | ||
|
||
Slice value_slice(ObjectCacheHandlePtr handle) override; | ||
|
||
Status adjust_capacity(int64_t delta, size_t min_capacity) override; | ||
|
||
Status set_capacity(size_t capacity) override; | ||
|
||
size_t capacity() const override; | ||
|
||
size_t usage() const override; | ||
|
||
size_t lookup_count() const override; | ||
|
||
size_t hit_count() const override; | ||
|
||
const ObjectCacheMetrics metrics() const override; | ||
|
||
Status prune() override; | ||
|
||
Status shutdown() override; | ||
|
||
private: | ||
bool _check_write(size_t charge, ObjectCacheWriteOptions* options) const; | ||
|
||
ObjectCacheOptions _options; | ||
std::shared_ptr<Cache> _cache; | ||
}; | ||
|
||
} // namespace starrocks |
Oops, something went wrong.