diff options
author | Greg Soltis <gsoltis@google.com> | 2018-03-22 15:45:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-22 15:45:05 -0700 |
commit | 4afaafdc770612185c4e11d3f09226ce168462a5 (patch) | |
tree | 21c912e4c719a1b0a0961457017efce1f4b385c0 /Firestore/Source/Local/FSTLevelDBMigrations.mm | |
parent | 1e769d708459ff64ca3571ab562377cc56a9d637 (diff) |
Change write groups to use transactions (#912)
* Start work on leveldb transactions
* Style
* Working API. Not plumbed in yet
* Move files into correct place
* Wrangling file locations and associations
* Tests pass
* Add some comments
* style
* Fix copyright
* Rewrite iterator internals to handle deletion-while-iterating. Also add tests for same
* Switch to strings instead of slices
* Style
* More style fixes
* Start switching writegroup over
* Swap out write group tracking for transaction usage
* Style
* Response to feedback before updating docs
* Style
* Add comment
* Initialize version_
* Satisfy the linter
* Start switching writegroup over
* Swap out write group tracking for transaction usage
* Style
* Checkpoint before implementing BatchDescription
* Style
* Everything passing
* Drop unused function
* Style
* Renaming
* Style
* Add log line
* Style
* Add debug log line for commits, drop unused BatchDescription
Diffstat (limited to 'Firestore/Source/Local/FSTLevelDBMigrations.mm')
-rw-r--r-- | Firestore/Source/Local/FSTLevelDBMigrations.mm | 58 |
1 files changed, 25 insertions, 33 deletions
diff --git a/Firestore/Source/Local/FSTLevelDBMigrations.mm b/Firestore/Source/Local/FSTLevelDBMigrations.mm index 7595c53..7f521d1 100644 --- a/Firestore/Source/Local/FSTLevelDBMigrations.mm +++ b/Firestore/Source/Local/FSTLevelDBMigrations.mm @@ -16,13 +16,12 @@ #include "Firestore/Source/Local/FSTLevelDBMigrations.h" +#include <absl/strings/match.h> #include "leveldb/write_batch.h" #import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" -#import "Firestore/Source/Local/FSTLevelDB.h" #import "Firestore/Source/Local/FSTLevelDBKey.h" #import "Firestore/Source/Local/FSTLevelDBQueryCache.h" -#import "Firestore/Source/Local/FSTWriteGroup.h" #import "Firestore/Source/Util/FSTAssert.h" NS_ASSUME_NONNULL_BEGIN @@ -30,6 +29,7 @@ NS_ASSUME_NONNULL_BEGIN // Current version of the schema defined in this file. static FSTLevelDBSchemaVersion kSchemaVersion = 2; +using firebase::firestore::local::LevelDbTransaction; using leveldb::DB; using leveldb::Iterator; using leveldb::Status; @@ -38,24 +38,24 @@ using leveldb::WriteOptions; /** * Ensures that the global singleton target metadata row exists in LevelDB. - * @param db The db in which to require the row. */ -static void EnsureTargetGlobal(std::shared_ptr<DB> db, FSTWriteGroup *group) { - FSTPBTargetGlobal *targetGlobal = [FSTLevelDBQueryCache readTargetMetadataFromDB:db]; +static void EnsureTargetGlobal(LevelDbTransaction *transaction) { + FSTPBTargetGlobal *targetGlobal = + [FSTLevelDBQueryCache readTargetMetadataWithTransaction:transaction]; if (!targetGlobal) { - [group setMessage:[FSTPBTargetGlobal message] forKey:[FSTLevelDBTargetGlobalKey key]]; + transaction->Put([FSTLevelDBTargetGlobalKey key], [FSTPBTargetGlobal message]); } } /** * Save the given version number as the current version of the schema of the database. * @param version The version to save - * @param group The transaction in which to save the new version number + * @param transaction The transaction in which to save the new version number */ -static void SaveVersion(FSTLevelDBSchemaVersion version, FSTWriteGroup *group) { +static void SaveVersion(FSTLevelDBSchemaVersion version, LevelDbTransaction *transaction) { std::string key = [FSTLevelDBVersionKey key]; std::string version_string = std::to_string(version); - [group setData:version_string forKey:key]; + transaction->Put(key, version_string); } /** @@ -65,30 +65,32 @@ static void SaveVersion(FSTLevelDBSchemaVersion version, FSTWriteGroup *group) { * * It assumes the metadata has already been written and is able to be read in this transaction. */ -static void AddTargetCount(std::shared_ptr<DB> db, FSTWriteGroup *group) { - std::unique_ptr<Iterator> it(db->NewIterator([FSTLevelDB standardReadOptions])); - Slice start_key = [FSTLevelDBTargetKey keyPrefix]; +static void AddTargetCount(LevelDbTransaction *transaction) { + std::unique_ptr<LevelDbTransaction::Iterator> it(transaction->NewIterator()); + std::string start_key = [FSTLevelDBTargetKey keyPrefix]; it->Seek(start_key); int32_t count = 0; - while (it->Valid() && it->key().starts_with(start_key)) { + while (it->Valid() && absl::StartsWith(it->key(), start_key)) { count++; it->Next(); } - FSTPBTargetGlobal *targetGlobal = [FSTLevelDBQueryCache readTargetMetadataFromDB:db]; + FSTPBTargetGlobal *targetGlobal = + [FSTLevelDBQueryCache readTargetMetadataWithTransaction:transaction]; FSTCAssert(targetGlobal != nil, @"We should have a metadata row as it was added in an earlier migration"); targetGlobal.targetCount = count; - [group setMessage:targetGlobal forKey:[FSTLevelDBTargetGlobalKey key]]; + transaction->Put([FSTLevelDBTargetGlobalKey key], targetGlobal); } @implementation FSTLevelDBMigrations -+ (FSTLevelDBSchemaVersion)schemaVersionForDB:(std::shared_ptr<DB>)db { ++ (FSTLevelDBSchemaVersion)schemaVersionWithTransaction: + (firebase::firestore::local::LevelDbTransaction *)transaction { std::string key = [FSTLevelDBVersionKey key]; std::string version_string; - Status status = db->Get([FSTLevelDB standardReadOptions], key, &version_string); + Status status = transaction->Get(key, &version_string); if (status.IsNotFound()) { return 0; } else { @@ -96,34 +98,24 @@ static void AddTargetCount(std::shared_ptr<DB> db, FSTWriteGroup *group) { } } -+ (void)runMigrationsOnDB:(std::shared_ptr<DB>)db { - FSTWriteGroup *group = [FSTWriteGroup groupWithAction:@"Migrations"]; - FSTLevelDBSchemaVersion currentVersion = [self schemaVersionForDB:db]; ++ (void)runMigrationsWithTransaction:(firebase::firestore::local::LevelDbTransaction *)transaction { + FSTLevelDBSchemaVersion currentVersion = [self schemaVersionWithTransaction:transaction]; // Each case in this switch statement intentionally falls through. This lets us // start at the current schema version and apply any migrations that have not yet // been applied, to bring us up to current, as defined by the kSchemaVersion constant. switch (currentVersion) { case 0: - EnsureTargetGlobal(db, group); + EnsureTargetGlobal(transaction); // Fallthrough case 1: - // We need to make sure we have metadata, since we're going to read and modify it - // in this migration. Commit the current transaction and start a new one. Since we're - // committing, we need to save a version. It's safe to save this one, if we crash - // after saving we'll resume from this step when we try to migrate. - SaveVersion(1, group); - [group writeToDB:db]; - group = [FSTWriteGroup groupWithAction:@"Migrations"]; - AddTargetCount(db, group); + // We're now guaranteed that the target global exists. We can safely add a count to it. + AddTargetCount(transaction); // Fallthrough default: if (currentVersion < kSchemaVersion) { - SaveVersion(kSchemaVersion, group); + SaveVersion(kSchemaVersion, transaction); } } - if (!group.isEmpty) { - [group writeToDB:db]; - } } @end |