fix some leveldb errors on transition to standby

turns out you gotta free the iterators. wow!!
custom
jacqueline 2 years ago
parent e8a972cc7f
commit 64d9cec8b0
  1. 48
      src/database/database.cpp

@ -46,19 +46,6 @@ static const char kTrackIdKey[] = "next_track_id";
static std::atomic<bool> sIsDbOpen(false);
template <typename Parser>
auto IterateAndParse(leveldb::Iterator* it, std::size_t limit, Parser p)
-> void {
for (int i = 0; i < limit; i++) {
if (!it->Valid()) {
delete it;
break;
}
std::invoke(p, it->key(), it->value());
it->Next();
}
}
auto Database::Open(IFileGatherer& gatherer, ITagParser& parser)
-> cpp::result<Database*, DatabaseError> {
// TODO(jacqueline): Why isn't compare_and_exchange_* available?
@ -66,8 +53,11 @@ auto Database::Open(IFileGatherer& gatherer, ITagParser& parser)
return cpp::fail(DatabaseError::ALREADY_OPEN);
}
leveldb::sBackgroundThread.reset(
tasks::Worker::Start<tasks::Type::kDatabaseBackground>());
if (!leveldb::sBackgroundThread) {
leveldb::sBackgroundThread.reset(
tasks::Worker::Start<tasks::Type::kDatabaseBackground>());
}
std::shared_ptr<tasks::Worker> worker(
tasks::Worker::Start<tasks::Type::kDatabase>());
return worker
@ -120,8 +110,6 @@ Database::~Database() {
delete db_;
delete cache_;
leveldb::sBackgroundThread.reset();
sIsDbOpen.store(false);
}
@ -136,7 +124,7 @@ auto Database::Update() -> std::future<void> {
// indexes, but my brain hurts.
ESP_LOGI(kTag, "dropping stale indexes");
{
leveldb::Iterator* it = db_->NewIterator(read_options);
std::unique_ptr<leveldb::Iterator> it{db_->NewIterator(read_options)};
OwningSlice prefix = EncodeAllIndexesPrefix();
it->Seek(prefix.slice);
while (it->Valid() && it->key().starts_with(prefix.slice)) {
@ -151,7 +139,7 @@ auto Database::Update() -> std::future<void> {
.stage = event::UpdateProgress::Stage::kVerifyingExistingTracks,
});
{
leveldb::Iterator* it = db_->NewIterator(read_options);
std::unique_ptr<leveldb::Iterator> it{db_->NewIterator(read_options)};
OwningSlice prefix = EncodeDataPrefix();
it->Seek(prefix.slice);
while (it->Valid() && it->key().starts_with(prefix.slice)) {
@ -200,7 +188,6 @@ auto Database::Update() -> std::future<void> {
it->Next();
}
delete it;
}
// Stage 2: search for newly added files.
@ -302,7 +289,8 @@ auto Database::GetBulkTracks(std::vector<TrackId> ids)
std::vector<TrackId> sorted_ids = ids;
std::sort(sorted_ids.begin(), sorted_ids.end());
leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions{});
std::unique_ptr<leveldb::Iterator> it{
db_->NewIterator(leveldb::ReadOptions{})};
for (const TrackId& id : sorted_ids) {
OwningSlice key = EncodeDataKey(id);
it->Seek(key.slice);
@ -476,7 +464,8 @@ auto Database::dbCreateIndexesForTrack(Track track) -> void {
template <typename T>
auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
// Work out our starting point. Sometimes this will already done.
leveldb::Iterator* it = db_->NewIterator(leveldb::ReadOptions());
std::unique_ptr<leveldb::Iterator> it{
db_->NewIterator(leveldb::ReadOptions{})};
it->Seek(c.start_key);
// Fix off-by-one if we just changed direction.
@ -509,11 +498,8 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
}
}
std::unique_ptr<leveldb::Iterator> iterator(it);
if (iterator != nullptr) {
if (!iterator->Valid() || !it->key().starts_with(c.prefix)) {
iterator.reset();
}
if (!it->Valid() || !it->key().starts_with(c.prefix)) {
it.reset();
}
// Put results into canonical order if we were iterating backwards.
@ -524,9 +510,9 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
// Work out the new continuations.
std::optional<Continuation<T>> next_page;
if (c.forward) {
if (iterator != nullptr) {
if (it != nullptr) {
// We were going forward, and now we want the next page.
std::string key = iterator->key().ToString();
std::string key = it->key().ToString();
next_page = Continuation<T>{
.prefix = c.prefix,
.start_key = key,
@ -561,9 +547,9 @@ auto Database::dbGetPage(const Continuation<T>& c) -> Result<T>* {
.page_size = c.page_size,
};
} else {
if (iterator != nullptr) {
if (it != nullptr) {
// We were going backwards, and we still want to go backwards.
std::string key = iterator->key().ToString();
std::string key = it->key().ToString();
prev_page = Continuation<T>{
.prefix = c.prefix,
.start_key = key,

Loading…
Cancel
Save