Skip to content

Commit 0352c1f

Browse files
authored
Leveldb schema/key change for indexing (#9268)
1 parent 114a5b8 commit 0352c1f

File tree

3 files changed

+441
-0
lines changed

3 files changed

+441
-0
lines changed

Firestore/core/src/local/leveldb_key.cc

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ const char* kCollectionParentsTable = "collection_parent";
5050
const char* kRemoteDocumentReadTimeTable = "remote_document_read_time";
5151
const char* kBundlesTable = "bundles";
5252
const char* kNamedQueriesTable = "named_queries";
53+
const char* kIndexConfigurationTable = "index_configuration";
54+
const char* kIndexStateTable = "index_state";
55+
const char* kIndexEntriesTable = "index_entries";
5356

5457
/**
5558
* Labels for the components of keys. These serve to make keys self-describing.
@@ -115,6 +118,15 @@ enum ComponentLabel {
115118
/** A component containing the name of a named query. */
116119
QueryName = 18,
117120

121+
/** A component containing a index id. */
122+
IndexId = 19,
123+
124+
/** A component containing an array index value. */
125+
IndexArrayValue = 20,
126+
127+
/** A component containing a directional index value. */
128+
IndexDirectionalValue = 21,
129+
118130
/**
119131
* A path segment describes just a single segment in a resource path. Path
120132
* segments that occur sequentially in a key represent successive segments in
@@ -201,6 +213,18 @@ class Reader {
201213
return ReadLabeledString(ComponentLabel::QueryName);
202214
}
203215

216+
int32_t ReadIndexId() {
217+
return ReadLabeledInt32(ComponentLabel::IndexId);
218+
}
219+
220+
std::string ReadIndexArrayValue() {
221+
return ReadLabeledString(ComponentLabel::IndexArrayValue);
222+
}
223+
224+
std::string ReadIndexDirectionalValue() {
225+
return ReadLabeledString(ComponentLabel::IndexDirectionalValue);
226+
}
227+
204228
/**
205229
* Reads a snapshot version, encoded as a component label and a pair of
206230
* seconds (int64) and nanoseconds (int32).
@@ -567,6 +591,21 @@ std::string Reader::Describe() {
567591
if (ok_) {
568592
absl::StrAppend(&description, " query_name=", query_name);
569593
}
594+
} else if (label == ComponentLabel::IndexId) {
595+
int32_t index_id = ReadIndexId();
596+
if (ok_) {
597+
absl::StrAppend(&description, " index_id=", index_id);
598+
}
599+
} else if (label == ComponentLabel::IndexArrayValue) {
600+
std::string value = ReadIndexArrayValue();
601+
if (ok_) {
602+
absl::StrAppend(&description, " array_value=", std::move(value));
603+
}
604+
} else if (label == ComponentLabel::IndexDirectionalValue) {
605+
std::string value = ReadIndexDirectionalValue();
606+
if (ok_) {
607+
absl::StrAppend(&description, " directional_value=", std::move(value));
608+
}
570609
} else {
571610
absl::StrAppend(&description, " unknown label=", static_cast<int>(label));
572611
Fail();
@@ -650,6 +689,18 @@ class Writer {
650689
}
651690
}
652691

692+
void WriteIndexId(int32_t id) {
693+
WriteLabeledInt32(ComponentLabel::IndexId, id);
694+
}
695+
696+
void WriteIndexArrayValue(absl::string_view value) {
697+
WriteLabeledString(ComponentLabel::IndexArrayValue, value);
698+
}
699+
700+
void WriteIndexDirectionalValue(absl::string_view value) {
701+
WriteLabeledString(ComponentLabel::IndexDirectionalValue, value);
702+
}
703+
653704
private:
654705
/** Writes a component label to the given key destination. */
655706
void WriteComponentLabel(ComponentLabel label) {
@@ -1094,6 +1145,87 @@ bool LevelDbNamedQueryKey::Decode(absl::string_view key) {
10941145
return reader.ok();
10951146
}
10961147

1148+
std::string LevelDbIndexConfigurationKey::KeyPrefix() {
1149+
Writer writer;
1150+
writer.WriteTableName(kIndexConfigurationTable);
1151+
return writer.result();
1152+
}
1153+
1154+
std::string LevelDbIndexConfigurationKey::Key(int32_t id) {
1155+
Writer writer;
1156+
writer.WriteTableName(kIndexConfigurationTable);
1157+
writer.WriteIndexId(id);
1158+
writer.WriteTerminator();
1159+
return writer.result();
1160+
}
1161+
1162+
bool LevelDbIndexConfigurationKey::Decode(absl::string_view key) {
1163+
Reader reader{key};
1164+
reader.ReadTableNameMatching(kIndexConfigurationTable);
1165+
index_id_ = reader.ReadIndexId();
1166+
reader.ReadTerminator();
1167+
return reader.ok();
1168+
}
1169+
1170+
std::string LevelDbIndexStateKey::KeyPrefix() {
1171+
Writer writer;
1172+
writer.WriteTableName(kIndexStateTable);
1173+
return writer.result();
1174+
}
1175+
1176+
std::string LevelDbIndexStateKey::Key(int32_t index_id,
1177+
absl::string_view user_id) {
1178+
Writer writer;
1179+
writer.WriteTableName(kIndexStateTable);
1180+
writer.WriteIndexId(index_id);
1181+
writer.WriteUserId(user_id);
1182+
writer.WriteTerminator();
1183+
return writer.result();
1184+
}
1185+
1186+
bool LevelDbIndexStateKey::Decode(absl::string_view key) {
1187+
Reader reader{key};
1188+
reader.ReadTableNameMatching(kIndexStateTable);
1189+
index_id_ = reader.ReadIndexId();
1190+
user_id_ = reader.ReadUserId();
1191+
reader.ReadTerminator();
1192+
return reader.ok();
1193+
}
1194+
1195+
std::string LevelDbIndexEntryKey::KeyPrefix() {
1196+
Writer writer;
1197+
writer.WriteTableName(kIndexEntriesTable);
1198+
return writer.result();
1199+
}
1200+
1201+
std::string LevelDbIndexEntryKey::Key(int32_t index_id,
1202+
absl::string_view user_id,
1203+
absl::string_view array_value,
1204+
absl::string_view dicrectional_value,
1205+
absl::string_view document_key) {
1206+
Writer writer;
1207+
writer.WriteTableName(kIndexEntriesTable);
1208+
writer.WriteIndexId(index_id);
1209+
writer.WriteUserId(user_id);
1210+
writer.WriteIndexArrayValue(array_value);
1211+
writer.WriteIndexDirectionalValue(dicrectional_value);
1212+
writer.WriteDocumentId(document_key);
1213+
writer.WriteTerminator();
1214+
return writer.result();
1215+
}
1216+
1217+
bool LevelDbIndexEntryKey::Decode(absl::string_view key) {
1218+
Reader reader{key};
1219+
reader.ReadTableNameMatching(kIndexEntriesTable);
1220+
index_id_ = reader.ReadIndexId();
1221+
user_id_ = reader.ReadUserId();
1222+
array_value_ = reader.ReadIndexArrayValue();
1223+
directional_value_ = reader.ReadIndexDirectionalValue();
1224+
document_key_ = reader.ReadDocumentId();
1225+
reader.ReadTerminator();
1226+
return reader.ok();
1227+
}
1228+
10971229
} // namespace local
10981230
} // namespace firestore
10991231
} // namespace firebase

Firestore/core/src/local/leveldb_key.h

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,23 @@ namespace local {
9797
// named_queries:
9898
// - table_name: string = "named_queries"
9999
// - name: string
100+
//
101+
// index_configuration:
102+
// - table_name: string = "index_configuration"
103+
// - index_id: int32_t
104+
//
105+
// index_state:
106+
// - table_name: string = "index_state"
107+
// - index_id: int32_t
108+
// - user_id: string
109+
//
110+
// index_entries:
111+
// - table_name: string = "index_entries"
112+
// - index_id: int32_t
113+
// - user_id: string
114+
// - array_value: string
115+
// - directional_value: string
116+
// - document_name: string
100117

101118
/**
102119
* Parses the given key and returns a human readable description of its
@@ -713,6 +730,150 @@ class LevelDbNamedQueryKey {
713730
std::string name_;
714731
};
715732

733+
/**
734+
* A key in the index_configuration table, storing the index definition proto,
735+
* and the collection (group) it applies to.
736+
*/
737+
class LevelDbIndexConfigurationKey {
738+
public:
739+
/**
740+
* Creates a key prefix that points just before the first key of the table.
741+
*/
742+
static std::string KeyPrefix();
743+
744+
/**
745+
* Creates a key that points to the key for the given index id.
746+
*/
747+
static std::string Key(int32_t id);
748+
749+
/**
750+
* Decodes the given complete key, storing the decoded values in this
751+
* instance.
752+
*
753+
* @return true if the key successfully decoded, false otherwise. If false is
754+
* returned, this instance is in an undefined state until the next call to
755+
* `Decode()`.
756+
*/
757+
ABSL_MUST_USE_RESULT
758+
bool Decode(absl::string_view key);
759+
760+
/** The index id for this entry. */
761+
int32_t index_id() const {
762+
return index_id_;
763+
}
764+
765+
private:
766+
int32_t index_id_;
767+
};
768+
769+
/**
770+
* A key in the index_state table, storing the per index per user state tracking
771+
* backfilling state for each index.
772+
*/
773+
class LevelDbIndexStateKey {
774+
public:
775+
/**
776+
* Creates a key prefix that points just before the first key of the table.
777+
*/
778+
static std::string KeyPrefix();
779+
780+
/**
781+
* Creates a key that points to the key for the given index id and user id.
782+
*/
783+
static std::string Key(int32_t index_id, absl::string_view user_id);
784+
785+
/**
786+
* Decodes the given complete key, storing the decoded values in this
787+
* instance.
788+
*
789+
* @return true if the key successfully decoded, false otherwise. If false is
790+
* returned, this instance is in an undefined state until the next call to
791+
* `Decode()`.
792+
*/
793+
ABSL_MUST_USE_RESULT
794+
bool Decode(absl::string_view key);
795+
796+
/** The index id for this entry. */
797+
int32_t index_id() const {
798+
return index_id_;
799+
}
800+
801+
/** The user id for this entry. */
802+
const std::string& user_id() const {
803+
return user_id_;
804+
}
805+
806+
private:
807+
int32_t index_id_;
808+
std::string user_id_;
809+
};
810+
811+
/**
812+
* A key in the index_entries table, storing the the encoded entries for all
813+
* fields used by a given index.
814+
*
815+
* Note: `array_value` is expected to be set for all queries.
816+
*/
817+
class LevelDbIndexEntryKey {
818+
public:
819+
/**
820+
* Creates a key prefix that points just before the first key of the table.
821+
*/
822+
static std::string KeyPrefix();
823+
824+
/**
825+
* Creates a key that points to the key for the given index entry fields.
826+
*/
827+
static std::string Key(int32_t index_id,
828+
absl::string_view user_id,
829+
absl::string_view array_value,
830+
absl::string_view directional_value,
831+
absl::string_view document_name);
832+
833+
/**
834+
* Decodes the given complete key, storing the decoded values in this
835+
* instance.
836+
*
837+
* @return true if the key successfully decoded, false otherwise. If false is
838+
* returned, this instance is in an undefined state until the next call to
839+
* `Decode()`.
840+
*/
841+
ABSL_MUST_USE_RESULT
842+
bool Decode(absl::string_view key);
843+
844+
/** The index id for this entry. */
845+
int32_t index_id() const {
846+
return index_id_;
847+
}
848+
849+
/** The user id for this entry. */
850+
const std::string& user_id() const {
851+
return user_id_;
852+
}
853+
854+
/** The encoded array index value for this entry. */
855+
const std::string& array_value() const {
856+
return array_value_;
857+
}
858+
859+
/** The encoded directional index value for this entry. */
860+
const std::string& directional_value() const {
861+
return directional_value_;
862+
}
863+
864+
/** The document key this entry points to. */
865+
const std::string& document_key() const {
866+
return document_key_;
867+
}
868+
869+
private:
870+
int32_t index_id_;
871+
std::string user_id_;
872+
std::string array_value_;
873+
std::string directional_value_;
874+
std::string document_key_;
875+
};
876+
716877
} // namespace local
717878
} // namespace firestore
718879
} // namespace firebase

0 commit comments

Comments
 (0)