Keys stored in alphabetical order and need to follow ghobject_t comparison
rule. "generation" and "shard_id" are optional fields for object key, but
a default ghobject with UINT64_MAX generation(by default) will larger than
the same ghobject with other generation. GenericObjectMap rejects to store
generation if generation is UINT64_MAX in order to reduce too much words
in key. So we need to add a MAX sign to the end of key to make ordering
is same with ghobject's comparison rule.
For example:
_GHOBJTOSEQ_:1%e1ds0_head!
D168A7E8!!1!!benchmark_last_metadata!head
_GHOBJTOSEQ_:1%e1ds0_head!
D168A7E8!!1!!benchmark_last_metadata!head!78!0
The first key should larger than the second in ghobject_t ordering because
of generation. But the first key less than the second in GenericObjectMap.
_GHOBJTOSEQ_:1%e1ds0_head!
D168A7E8!!1!!benchmark_last_metadata!head
_GHOBJTOSEQ_:1%e1ds0_head!
D168A7E8!!1!!benchmark_last_metadata!head!78!0
After we add KEY_ENDING, '!' is (21) in hexadecimal:
_GHOBJTOSEQ_:1%e1ds0_head!
D168A7E8!!1!!benchmark_last_metadata!head(21)78!0(FF)
_GHOBJTOSEQ_:1%e1ds0_head!
D168A7E8!!1!!benchmark_last_metadata!head(FF)
Fix bug #10119
Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
#include "include/assert.h"
#define dout_subsys ceph_subsys_keyvaluestore
+
const string GenericObjectMap::GLOBAL_STATE_KEY = "HEADER";
const string GenericObjectMap::USER_PREFIX = "_SEQ_";
// so use "!" to separated
const string GenericObjectMap::GHOBJECT_KEY_SEP_S = "!";
const char GenericObjectMap::GHOBJECT_KEY_SEP_C = '!';
+const char GenericObjectMap::GHOBJECT_KEY_ENDING = 0xFF;
// ============== GenericObjectMap Key Function =================
t = buf;
end = t + sizeof(buf);
- t += snprintf(t, end - t, "%llx", (long long unsigned)oid.generation);
+ t += snprintf(t, end - t, "%016llx", (long long unsigned)oid.generation);
full_name += string(buf);
full_name.append(GHOBJECT_KEY_SEP_S);
full_name += string(buf);
}
+ full_name.append(1, GHOBJECT_KEY_ENDING);
+
return full_name;
}
static const string GHOBJECT_KEY_SEP_S;
static const char GHOBJECT_KEY_SEP_C;
+ static const char GHOBJECT_KEY_ENDING;
private:
/// Implicit lock on Header->seq