// version 5.
void ghobject_t::encode(bufferlist& bl) const
{
+ // when changing this, remember to update encoded_size() too.
ENCODE_START(6, 3, bl);
::encode(hobj.key, bl);
::encode(hobj.oid, bl);
ENCODE_FINISH(bl);
}
+size_t ghobject_t::encoded_size() const
+{
+ // this is not in order of encoding or appearance, but rather
+ // in order of known constants first, so it can be (mostly) computed
+ // at compile time.
+ // - encoding header + 3 string lengths
+ size_t r = sizeof(ceph_le32) + 2 * sizeof(__u8) + 3 * sizeof(__u32);
+
+ // hobj.snap
+ r += sizeof(uint64_t);
+
+ // hobj.hash
+ r += sizeof(uint32_t);
+
+ // hobj.max
+ r += sizeof(bool);
+
+ // hobj.pool
+ r += sizeof(uint64_t);
+
+ // hobj.generation
+ r += sizeof(uint64_t);
+
+ // hobj.shard_id
+ r += sizeof(int8_t);
+
+ // max
+ r += sizeof(bool);
+
+ // hobj.key
+ r += hobj.key.size();
+
+ // hobj.oid
+ r += hobj.oid.name.size();
+
+ // hobj.nspace
+ r += hobj.nspace.size();
+
+ return r;
+}
+
void ghobject_t::decode(bufferlist::iterator& bl)
{
DECODE_START_LEGACY_COMPAT_LEN(6, 3, 3, bl);
void encode(bufferlist& bl) const;
void decode(bufferlist::iterator& bl);
void decode(json_spirit::Value& v);
+ size_t encoded_size() const;
void dump(Formatter *f) const;
static void generate_test_instances(list<ghobject_t*>& o);
friend int cmp_nibblewise(const ghobject_t& l, const ghobject_t& r);
return 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4 + tbl.length();
else {
//layout: data_bl + op_bl + coll_index + object_index + data
- //TODO: maybe we need better way to get encoded bytes;
- bufferlist bl;
- ::encode(coll_index, bl);
- ::encode(object_index, bl);
+ // coll_index size, object_index size and sizeof(transaction_data)
+ // all here, so they may be computed at compile-time
+ size_t final_size = sizeof(__u32) * 2 + sizeof(data);
+
+ // coll_index second and object_index second
+ final_size += (coll_index.size() + object_index.size()) * sizeof(__le32);
+
+ // coll_index first
+ for (auto p = coll_index.begin(); p != coll_index.end(); ++p) {
+ final_size += p->first.encoded_size();
+ }
+
+ // object_index first
+ for (auto p = object_index.begin(); p != object_index.end(); ++p) {
+ final_size += p->first.encoded_size();
+ }
+
return data_bl.length() +
op_bl.length() +
- bl.length() +
- sizeof(data);
+ final_size;
}
}
void coll_t::encode(bufferlist& bl) const
{
+ // when changing this, remember to update encoded_size() too.
if (is_temp()) {
// can't express this as v2...
__u8 struct_v = 3;
}
}
+size_t coll_t::encoded_size() const
+{
+ size_t r = sizeof(__u8);
+ if (is_temp()) {
+ // v3
+ r += sizeof(__u32);
+ if (_str) {
+ r += strlen(_str);
+ }
+ } else {
+ // v2
+ // 1. type
+ r += sizeof(__u8);
+ // 2. pgid
+ // - encoding header
+ r += sizeof(ceph_le32) + 2 * sizeof(__u8);
+ // - pg_t
+ r += sizeof(__u8) + sizeof(uint64_t) + 2 * sizeof(uint32_t);
+ // - shard_id_t
+ r += sizeof(int8_t);
+ // 3. snapid_t
+ r += sizeof(uint64_t);
+ }
+
+ return r;
+}
+
void coll_t::decode(bufferlist::iterator& bl)
{
__u8 struct_v;
void encode(bufferlist& bl) const;
void decode(bufferlist::iterator& bl);
+ size_t encoded_size() const;
inline bool operator==(const coll_t& rhs) const {
// only compare type if meta