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
12 namespace ROCKSDB_NAMESPACE {
13
GetAllKeyVersions(DB * db,Slice begin_key,Slice end_key,size_t max_num_ikeys,std::vector<KeyVersion> * key_versions)14 Status GetAllKeyVersions(DB* db, Slice begin_key, Slice end_key,
15 size_t max_num_ikeys,
16 std::vector<KeyVersion>* key_versions) {
17 if (nullptr == db) {
18 return Status::InvalidArgument("db cannot be null.");
19 }
20 return GetAllKeyVersions(db, db->DefaultColumnFamily(), begin_key, end_key,
21 max_num_ikeys, key_versions);
22 }
23
GetAllKeyVersions(DB * db,ColumnFamilyHandle * cfh,Slice begin_key,Slice end_key,size_t max_num_ikeys,std::vector<KeyVersion> * key_versions)24 Status GetAllKeyVersions(DB* db, ColumnFamilyHandle* cfh, Slice begin_key,
25 Slice end_key, size_t max_num_ikeys,
26 std::vector<KeyVersion>* key_versions) {
27 if (nullptr == db) {
28 return Status::InvalidArgument("db cannot be null.");
29 }
30 if (nullptr == cfh) {
31 return Status::InvalidArgument("Column family handle cannot be null.");
32 }
33 if (nullptr == key_versions) {
34 return Status::InvalidArgument("key_versions cannot be null.");
35 }
36 key_versions->clear();
37
38 DBImpl* idb = static_cast<DBImpl*>(db->GetRootDB());
39 auto icmp = InternalKeyComparator(idb->GetOptions(cfh).comparator);
40 ReadRangeDelAggregator range_del_agg(&icmp,
41 kMaxSequenceNumber /* upper_bound */);
42 Arena arena;
43 ScopedArenaIterator iter(idb->NewInternalIterator(&arena, &range_del_agg,
44 kMaxSequenceNumber, cfh));
45
46 if (!begin_key.empty()) {
47 InternalKey ikey;
48 ikey.SetMinPossibleForUserKey(begin_key);
49 iter->Seek(ikey.Encode());
50 } else {
51 iter->SeekToFirst();
52 }
53
54 size_t num_keys = 0;
55 for (; iter->Valid(); iter->Next()) {
56 ParsedInternalKey ikey;
57 if (!ParseInternalKey(iter->key(), &ikey)) {
58 return Status::Corruption("Internal Key [" + iter->key().ToString() +
59 "] parse error!");
60 }
61
62 if (!end_key.empty() &&
63 icmp.user_comparator()->Compare(ikey.user_key, end_key) > 0) {
64 break;
65 }
66
67 key_versions->emplace_back(ikey.user_key.ToString() /* _user_key */,
68 iter->value().ToString() /* _value */,
69 ikey.sequence /* _sequence */,
70 static_cast<int>(ikey.type) /* _type */);
71 if (++num_keys >= max_num_ikeys) {
72 break;
73 }
74 }
75 return Status::OK();
76 }
77
78 } // namespace ROCKSDB_NAMESPACE
79
80 #endif // ROCKSDB_LITE
81