mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 00:14:07 +01:00
ircd::db: Improvements to cache interface.
This commit is contained in:
parent
a7f43fe48d
commit
8537cca439
2 changed files with 183 additions and 42 deletions
|
@ -34,19 +34,35 @@ namespace ircd::db
|
||||||
size_t usage(const rocksdb::Cache *const &);
|
size_t usage(const rocksdb::Cache *const &);
|
||||||
|
|
||||||
// Test if key exists
|
// Test if key exists
|
||||||
bool exists(rocksdb::Cache &, const string_view &key);
|
bool exists(const rocksdb::Cache &, const string_view &key);
|
||||||
bool exists(rocksdb::Cache *const &, const string_view &key);
|
bool exists(const rocksdb::Cache *const &, const string_view &key);
|
||||||
|
|
||||||
|
// Iterate the cache entries.
|
||||||
|
using cache_closure = std::function<void (const string_view &, const size_t &)>;
|
||||||
|
void for_each(const rocksdb::Cache &, const cache_closure &);
|
||||||
|
void for_each(const rocksdb::Cache *const &, const cache_closure &);
|
||||||
|
|
||||||
|
// Manually cache a key/value directly
|
||||||
|
bool insert(rocksdb::Cache &, const string_view &key, unique_buffer<const_buffer>);
|
||||||
|
bool insert(rocksdb::Cache *const &, const string_view &key, unique_buffer<const_buffer>);
|
||||||
|
|
||||||
|
// Manually cache a copy of key/value
|
||||||
|
bool insert(rocksdb::Cache &, const string_view &key, const string_view &value);
|
||||||
|
bool insert(rocksdb::Cache *const &, const string_view &key, const string_view &value);
|
||||||
|
|
||||||
// Remove key if it exists
|
// Remove key if it exists
|
||||||
void remove(rocksdb::Cache &, const string_view &key);
|
bool remove(rocksdb::Cache &, const string_view &key);
|
||||||
void remove(rocksdb::Cache *const &, const string_view &key);
|
bool remove(rocksdb::Cache *const &, const string_view &key);
|
||||||
|
|
||||||
// Clear the cache (won't clear entries which are actively referenced)
|
// Clear the cache (won't clear entries which are actively referenced)
|
||||||
void clear(rocksdb::Cache &);
|
void clear(rocksdb::Cache &);
|
||||||
void clear(rocksdb::Cache *const &);
|
void clear(rocksdb::Cache *const &);
|
||||||
|
|
||||||
// Iterate the cache entries.
|
// Read the key from disk into cache; yields when done; returns exists.
|
||||||
using cache_closure = std::function<void (const string_view &, const size_t &)>;
|
bool fetch(rocksdb::Cache &, column &, const string_view &key);
|
||||||
void for_each(rocksdb::Cache &, const cache_closure &);
|
bool fetch(rocksdb::Cache *const &, column &, const string_view &key);
|
||||||
void for_each(rocksdb::Cache *const &, const cache_closure &);
|
|
||||||
|
// Read the key from disk into cache asynchronously; returns immediately.
|
||||||
|
void prefetch(rocksdb::Cache &, column &, const string_view &key);
|
||||||
|
void prefetch(rocksdb::Cache *const &, column &, const string_view &key);
|
||||||
}
|
}
|
||||||
|
|
193
ircd/db.cc
193
ircd/db.cc
|
@ -5785,7 +5785,159 @@ ircd::db::_seek_(rocksdb::Iterator &it,
|
||||||
//
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
ircd::db::for_each(rocksdb::Cache *const &cache,
|
ircd::db::prefetch(rocksdb::Cache *const &cache,
|
||||||
|
column &column,
|
||||||
|
const string_view &key)
|
||||||
|
{
|
||||||
|
if(cache)
|
||||||
|
return prefetch(*cache, column, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::db::prefetch(rocksdb::Cache &cache,
|
||||||
|
column &column,
|
||||||
|
const string_view &key)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::fetch(rocksdb::Cache *const &cache,
|
||||||
|
column &column,
|
||||||
|
const string_view &key)
|
||||||
|
{
|
||||||
|
if(cache)
|
||||||
|
return fetch(*cache, column, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::fetch(rocksdb::Cache &cache,
|
||||||
|
column &column,
|
||||||
|
const string_view &key)
|
||||||
|
{
|
||||||
|
const db::gopts opts
|
||||||
|
{
|
||||||
|
// skip rocksdb inserting this into the columns cache twice.
|
||||||
|
&cache == db::cache(column) || &cache == db::cache_compressed(column)?
|
||||||
|
db::get::NO_CACHE:
|
||||||
|
(enum db::get)0
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto closure{[&cache, &key]
|
||||||
|
(const string_view &value)
|
||||||
|
{
|
||||||
|
insert(cache, key, value);
|
||||||
|
}};
|
||||||
|
|
||||||
|
return column(key, std::nothrow, closure, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::db::clear(rocksdb::Cache *const &cache)
|
||||||
|
{
|
||||||
|
if(cache)
|
||||||
|
return clear(*cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::db::clear(rocksdb::Cache &cache)
|
||||||
|
{
|
||||||
|
cache.EraseUnRefEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::remove(rocksdb::Cache *const &cache,
|
||||||
|
const string_view &key)
|
||||||
|
{
|
||||||
|
if(cache)
|
||||||
|
return remove(*cache, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::remove(rocksdb::Cache &cache,
|
||||||
|
const string_view &key)
|
||||||
|
{
|
||||||
|
cache.Erase(slice(key));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::insert(rocksdb::Cache *const &cache,
|
||||||
|
const string_view &key,
|
||||||
|
const string_view &value)
|
||||||
|
{
|
||||||
|
if(cache)
|
||||||
|
return insert(*cache, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::insert(rocksdb::Cache &cache,
|
||||||
|
const string_view &key,
|
||||||
|
const string_view &value)
|
||||||
|
{
|
||||||
|
unique_buffer<const_buffer> buf
|
||||||
|
{
|
||||||
|
const_buffer{value}
|
||||||
|
};
|
||||||
|
|
||||||
|
return insert(cache, key, std::move(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::insert(rocksdb::Cache *const &cache,
|
||||||
|
const string_view &key,
|
||||||
|
unique_buffer<const_buffer> value)
|
||||||
|
{
|
||||||
|
if(cache)
|
||||||
|
return insert(*cache, key, std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::insert(rocksdb::Cache &cache,
|
||||||
|
const string_view &key,
|
||||||
|
unique_buffer<const_buffer> value)
|
||||||
|
{
|
||||||
|
static const auto deleter{[]
|
||||||
|
(const rocksdb::Slice &key, void *const value)
|
||||||
|
{
|
||||||
|
if(!value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const rocksdb::Slice *const &s
|
||||||
|
{
|
||||||
|
reinterpret_cast<const rocksdb::Slice *>(value)
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *const &buf
|
||||||
|
{
|
||||||
|
reinterpret_cast<const char *>(data(slice(*s)))
|
||||||
|
};
|
||||||
|
|
||||||
|
delete[] buf;
|
||||||
|
delete s;
|
||||||
|
}};
|
||||||
|
|
||||||
|
auto s
|
||||||
|
{
|
||||||
|
std::make_unique<rocksdb::Slice>(data(value), size(value))
|
||||||
|
};
|
||||||
|
|
||||||
|
// Note that because of the nullptr handle argument below, rocksdb
|
||||||
|
// will run the deleter if the insert throws; otherwise these
|
||||||
|
// operations have to be moved below the insert so the cleanup can
|
||||||
|
// happen out here. Right now this is all just here gratuitiously.
|
||||||
|
s.release();
|
||||||
|
value.release();
|
||||||
|
throw_on_error
|
||||||
|
{
|
||||||
|
cache.Insert(slice(key), s.get(), size(value), deleter, nullptr)
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::db::for_each(const rocksdb::Cache *const &cache,
|
||||||
const cache_closure &closure)
|
const cache_closure &closure)
|
||||||
{
|
{
|
||||||
if(cache)
|
if(cache)
|
||||||
|
@ -5793,16 +5945,16 @@ ircd::db::for_each(rocksdb::Cache *const &cache,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ircd::db::for_each(rocksdb::Cache &cache,
|
ircd::db::for_each(const rocksdb::Cache &cache,
|
||||||
const cache_closure &closure)
|
const cache_closure &closure)
|
||||||
{
|
{
|
||||||
thread_local rocksdb::Cache *_cache;
|
thread_local rocksdb::Cache *_cache;
|
||||||
_cache = &cache;
|
_cache = const_cast<rocksdb::Cache *>(&cache);
|
||||||
|
|
||||||
thread_local const cache_closure *_closure;
|
thread_local const cache_closure *_closure;
|
||||||
_closure = &closure;
|
_closure = &closure;
|
||||||
|
|
||||||
cache.ApplyToAllCacheEntries([]
|
_cache->ApplyToAllCacheEntries([]
|
||||||
(void *const data, const size_t charge)
|
(void *const data, const size_t charge)
|
||||||
{
|
{
|
||||||
assert(_cache);
|
assert(_cache);
|
||||||
|
@ -5828,45 +5980,18 @@ ircd::db::for_each(rocksdb::Cache &cache,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ircd::db::clear(rocksdb::Cache *const &cache)
|
|
||||||
{
|
|
||||||
if(cache)
|
|
||||||
clear(*cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::db::clear(rocksdb::Cache &cache)
|
|
||||||
{
|
|
||||||
cache.EraseUnRefEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::db::remove(rocksdb::Cache *const &cache,
|
|
||||||
const string_view &key)
|
|
||||||
{
|
|
||||||
if(cache)
|
|
||||||
remove(*cache, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ircd::db::remove(rocksdb::Cache &cache,
|
|
||||||
const string_view &key)
|
|
||||||
{
|
|
||||||
cache.Erase(slice(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ircd::db::exists(rocksdb::Cache *const &cache,
|
ircd::db::exists(const rocksdb::Cache *const &cache,
|
||||||
const string_view &key)
|
const string_view &key)
|
||||||
{
|
{
|
||||||
return cache? exists(*cache, key) : false;
|
return cache? exists(*cache, key) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ircd::db::exists(rocksdb::Cache &cache,
|
ircd::db::exists(const rocksdb::Cache &cache_,
|
||||||
const string_view &key)
|
const string_view &key)
|
||||||
{
|
{
|
||||||
|
auto &cache(const_cast<rocksdb::Cache &>(cache_));
|
||||||
const custom_ptr<rocksdb::Cache::Handle> handle
|
const custom_ptr<rocksdb::Cache::Handle> handle
|
||||||
{
|
{
|
||||||
cache.Lookup(slice(key)), [&cache](auto *const &handle)
|
cache.Lookup(slice(key)), [&cache](auto *const &handle)
|
||||||
|
|
Loading…
Reference in a new issue