OPTION(keyvaluestore_op_threads, OPT_INT, 2)
OPTION(keyvaluestore_op_thread_timeout, OPT_INT, 60)
OPTION(keyvaluestore_op_thread_suicide_timeout, OPT_INT, 180)
+OPTION(keyvaluestore_default_strip_size, OPT_INT, 4096) // Only affect new object
// max bytes to search ahead in journal searching for corruption
OPTION(journal_max_corrupt_search, OPT_U64, 10<<20)
perf_logger(NULL),
m_keyvaluestore_queue_max_ops(g_conf->keyvaluestore_queue_max_ops),
m_keyvaluestore_queue_max_bytes(g_conf->keyvaluestore_queue_max_bytes),
+ m_keyvaluestore_strip_size(g_conf->keyvaluestore_default_strip_size),
do_update(do_update)
{
ostringstream oss;
goto close_current_fd;
}
+ default_strip_size = m_keyvaluestore_strip_size;
backend.reset(dbomap);
}
case Transaction::OP_SETALLOCHINT:
{
- // TODO: can kvstore make use of the hint?
coll_t cid(i.decode_cid());
ghobject_t oid = i.decode_oid();
- i.decode_length(); // uint64_t expected_object_size
- i.decode_length(); // uint64_t expected_write_size
+ uint64_t expected_object_size = i.decode_length();
+ uint64_t expected_write_size = i.decode_length();
+ r = _set_alloc_hint(cid, oid, expected_object_size,
+ expected_write_size, t);
}
break;
return 0;
}
+int KeyValueStore::_set_alloc_hint(coll_t cid, const ghobject_t& oid,
+ uint64_t expected_object_size,
+ uint64_t expected_write_size,
+ BufferTransaction &t)
+{
+ dout(15) << __func__ << " " << cid << "/" << oid << " object_size "
+ << expected_object_size << " write_size "
+ << expected_write_size << dendl;
+
+ int r = 0;
+ StripObjectMap::StripObjectHeader *header;
+
+ r = t.lookup_cached_header(cid, oid, &header, false);
+ if (r < 0) {
+ dout(10) << __func__ << " " << cid << "/" << oid
+ << " failed to get header: r = " << r << dendl;
+ return r;
+ }
+
+ bool blank = true;
+ for (vector<char>::iterator it = header->bits.begin();
+ it != header->bits.end(); ++it) {
+ if (*it) {
+ blank = false;
+ break;
+ }
+ }
+
+ // Now only consider to change "strip_size" when the object is blank,
+ // because set_alloc_hint is expected to be very lightweight<O(1)>
+ if (blank) {
+ header->strip_size = expected_write_size;
+ }
+
+ dout(10) << __func__ << "" << cid << "/" << oid << " object_size "
+ << expected_object_size << " write_size "
+ << expected_write_size << " = " << r << dendl;
+
+ return r;
+}
+
const char** KeyValueStore::get_tracked_conf_keys() const
{
static const char* KEYS[] = {
"keyvaluestore_queue_max_ops",
"keyvaluestore_queue_max_bytes",
+ "keyvaluestore_strip_size",
NULL
};
return KEYS;
m_keyvaluestore_queue_max_ops = conf->keyvaluestore_queue_max_ops;
m_keyvaluestore_queue_max_bytes = conf->keyvaluestore_queue_max_bytes;
}
+ if (changed.count("keyvaluestore_default_strip_size")) {
+ m_keyvaluestore_strip_size = conf->keyvaluestore_default_strip_size;
+ default_strip_size = m_keyvaluestore_strip_size;
+ }
}
void KeyValueStore::dump_transactions(list<ObjectStore::Transaction*>& ls, uint64_t seq, OpSequencer *osr)
};
+static uint64_t default_strip_size = 1024;
+
class StripObjectMap: public GenericObjectMap {
public:
);
StripObjectMap(KeyValueDB *db): GenericObjectMap(db) {}
-
- static const uint64_t default_strip_size = 1024;
};
const ghobject_t& newoid, uint64_t srcoff,
uint64_t len, uint64_t dstoff, BufferTransaction &t);
int _remove(coll_t cid, const ghobject_t& oid, BufferTransaction &t);
-
+ int _set_alloc_hint(coll_t cid, const ghobject_t& oid,
+ uint64_t expected_object_size,
+ uint64_t expected_write_size,
+ BufferTransaction &t);
void start_sync() {}
void sync() {}
std::string m_osd_rollback_to_cluster_snap;
int m_keyvaluestore_queue_max_ops;
int m_keyvaluestore_queue_max_bytes;
+ int m_keyvaluestore_strip_size;
int do_update;