]>
Commit | Line | Data |
---|---|---|
1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. | |
2 | // This source code is licensed under both the GPLv2 (found in the | |
3 | // COPYING file in the root directory) and Apache 2.0 License | |
4 | // (found in the LICENSE.Apache file in the root directory). | |
5 | ||
6 | #ifndef ROCKSDB_LITE | |
7 | ||
8 | #include "rocksdb/utilities/debug.h" | |
9 | ||
10 | #include "db/db_impl/db_impl.h" | |
11 | #include "rocksdb/utilities/options_type.h" | |
12 | ||
13 | namespace ROCKSDB_NAMESPACE { | |
14 | ||
15 | static std::unordered_map<std::string, ValueType> value_type_string_map = { | |
16 | {"TypeDeletion", ValueType::kTypeDeletion}, | |
17 | {"TypeValue", ValueType::kTypeValue}, | |
18 | {"TypeMerge", ValueType::kTypeMerge}, | |
19 | {"TypeLogData", ValueType::kTypeLogData}, | |
20 | {"TypeColumnFamilyDeletion", ValueType::kTypeColumnFamilyDeletion}, | |
21 | {"TypeColumnFamilyValue", ValueType::kTypeColumnFamilyValue}, | |
22 | {"TypeColumnFamilyMerge", ValueType::kTypeColumnFamilyMerge}, | |
23 | {"TypeSingleDeletion", ValueType::kTypeSingleDeletion}, | |
24 | {"TypeColumnFamilySingleDeletion", | |
25 | ValueType::kTypeColumnFamilySingleDeletion}, | |
26 | {"TypeBeginPrepareXID", ValueType::kTypeBeginPrepareXID}, | |
27 | {"TypeEndPrepareXID", ValueType::kTypeEndPrepareXID}, | |
28 | {"TypeCommitXID", ValueType::kTypeCommitXID}, | |
29 | {"TypeRollbackXID", ValueType::kTypeRollbackXID}, | |
30 | {"TypeNoop", ValueType::kTypeNoop}, | |
31 | {"TypeColumnFamilyRangeDeletion", | |
32 | ValueType::kTypeColumnFamilyRangeDeletion}, | |
33 | {"TypeRangeDeletion", ValueType::kTypeRangeDeletion}, | |
34 | {"TypeColumnFamilyBlobIndex", ValueType::kTypeColumnFamilyBlobIndex}, | |
35 | {"TypeBlobIndex", ValueType::kTypeBlobIndex}, | |
36 | {"TypeBeginPersistedPrepareXID", ValueType::kTypeBeginPersistedPrepareXID}, | |
37 | {"TypeBeginUnprepareXID", ValueType::kTypeBeginUnprepareXID}, | |
38 | {"TypeDeletionWithTimestamp", ValueType::kTypeDeletionWithTimestamp}, | |
39 | {"TypeCommitXIDAndTimestamp", ValueType::kTypeCommitXIDAndTimestamp}, | |
40 | {"TypeWideColumnEntity", ValueType::kTypeWideColumnEntity}, | |
41 | {"TypeColumnFamilyWideColumnEntity", | |
42 | ValueType::kTypeColumnFamilyWideColumnEntity}}; | |
43 | ||
44 | std::string KeyVersion::GetTypeName() const { | |
45 | std::string type_name; | |
46 | if (SerializeEnum<ValueType>(value_type_string_map, | |
47 | static_cast<ValueType>(type), &type_name)) { | |
48 | return type_name; | |
49 | } else { | |
50 | return "Invalid"; | |
51 | } | |
52 | } | |
53 | ||
54 | Status GetAllKeyVersions(DB* db, Slice begin_key, Slice end_key, | |
55 | size_t max_num_ikeys, | |
56 | std::vector<KeyVersion>* key_versions) { | |
57 | if (nullptr == db) { | |
58 | return Status::InvalidArgument("db cannot be null."); | |
59 | } | |
60 | return GetAllKeyVersions(db, db->DefaultColumnFamily(), begin_key, end_key, | |
61 | max_num_ikeys, key_versions); | |
62 | } | |
63 | ||
64 | Status GetAllKeyVersions(DB* db, ColumnFamilyHandle* cfh, Slice begin_key, | |
65 | Slice end_key, size_t max_num_ikeys, | |
66 | std::vector<KeyVersion>* key_versions) { | |
67 | if (nullptr == db) { | |
68 | return Status::InvalidArgument("db cannot be null."); | |
69 | } | |
70 | if (nullptr == cfh) { | |
71 | return Status::InvalidArgument("Column family handle cannot be null."); | |
72 | } | |
73 | if (nullptr == key_versions) { | |
74 | return Status::InvalidArgument("key_versions cannot be null."); | |
75 | } | |
76 | key_versions->clear(); | |
77 | ||
78 | DBImpl* idb = static_cast<DBImpl*>(db->GetRootDB()); | |
79 | auto icmp = InternalKeyComparator(idb->GetOptions(cfh).comparator); | |
80 | ReadOptions read_options; | |
81 | Arena arena; | |
82 | ScopedArenaIterator iter( | |
83 | idb->NewInternalIterator(read_options, &arena, kMaxSequenceNumber, cfh)); | |
84 | ||
85 | if (!begin_key.empty()) { | |
86 | InternalKey ikey; | |
87 | ikey.SetMinPossibleForUserKey(begin_key); | |
88 | iter->Seek(ikey.Encode()); | |
89 | } else { | |
90 | iter->SeekToFirst(); | |
91 | } | |
92 | ||
93 | size_t num_keys = 0; | |
94 | for (; iter->Valid(); iter->Next()) { | |
95 | ParsedInternalKey ikey; | |
96 | Status pik_status = | |
97 | ParseInternalKey(iter->key(), &ikey, true /* log_err_key */); // TODO | |
98 | if (!pik_status.ok()) { | |
99 | return pik_status; | |
100 | } | |
101 | ||
102 | if (!end_key.empty() && | |
103 | icmp.user_comparator()->Compare(ikey.user_key, end_key) > 0) { | |
104 | break; | |
105 | } | |
106 | ||
107 | key_versions->emplace_back(ikey.user_key.ToString() /* _user_key */, | |
108 | iter->value().ToString() /* _value */, | |
109 | ikey.sequence /* _sequence */, | |
110 | static_cast<int>(ikey.type) /* _type */); | |
111 | if (++num_keys >= max_num_ikeys) { | |
112 | break; | |
113 | } | |
114 | } | |
115 | return Status::OK(); | |
116 | } | |
117 | ||
118 | } // namespace ROCKSDB_NAMESPACE | |
119 | ||
120 | #endif // ROCKSDB_LITE |