static void test_cache_timestamp(session &sess) { argument_data data("this is a timestamp test"); key k("this is a timestamp test key"); sess.transform(k); dnet_io_control ctl; memset(&ctl, 0, sizeof(ctl)); ctl.data = data.data(); dnet_current_time(&ctl.io.timestamp); ctl.io.flags = DNET_IO_FLAGS_CACHE; ctl.io.start = 5; ctl.io.size = data.size(); memcpy(&ctl.id, &k.id(), sizeof(dnet_id)); ctl.fd = -1; ELLIPTICS_REQUIRE(write_result, sess.write_data(ctl)); sleep(ctl.io.start + 2); ELLIPTICS_REQUIRE(read_result, sess.read_data(k, 0, 0)); auto io = read_result.get_one().io_attribute(); BOOST_REQUIRE_EQUAL(io->timestamp.tsec, ctl.io.timestamp.tsec); BOOST_REQUIRE_EQUAL(io->timestamp.tnsec, ctl.io.timestamp.tnsec); }
void async_result_handler<T>::complete(const error_info &error) { std::unique_lock<std::mutex> locker(m_data->lock); m_data->finished = true; dnet_current_time(&m_data->end); m_data->error = error; if (!error) { if (!check(&m_data->error)) m_data->error_handler(m_data->error, m_data->statuses); } if (m_data->final_handler) { m_data->final_handler(m_data->error); } m_data->condition.notify_all(); }
dnet_time async_result<T>::elapsed_time() const { dnet_time end; if (ready()) end = m_data->end; else dnet_current_time(&end); end.tsec -= m_data->start.tsec; if (end.tnsec < m_data->start.tnsec) { static const uint64_t sec = 1000 * 1000 * 1000; end.tnsec = end.tnsec + sec - m_data->start.tnsec; end.tsec -= 1; } return end; }
void dnet_create_meta_update(struct dnet_meta *m, struct timespec *ts, uint64_t flags_set, uint64_t flags_clear) { struct dnet_meta_update *mu = (struct dnet_meta_update *)m->data; m->size = sizeof(struct dnet_meta_update); m->type = DNET_META_UPDATE; if (!ts) { dnet_current_time(&mu->tm); } else { mu->tm.tsec = ts->tv_sec; mu->tm.tnsec = ts->tv_nsec; } mu->flags = 0; mu->flags |= flags_set; mu->flags &= ~flags_clear; dnet_convert_meta_update(mu); dnet_convert_meta(m); }
int dnet_update_ts_metadata_raw(struct dnet_meta_container *mc, uint64_t flags_set, uint64_t flags_clear) { struct dnet_meta m; void *data = mc->data; uint32_t size = mc->size; struct dnet_meta_update *mu; while (size) { if (size < sizeof(struct dnet_meta)) { return -1; } m = *(struct dnet_meta *)data; dnet_convert_meta(&m); if (m.size + sizeof(struct dnet_meta) > size) { return -1; } if (m.type == DNET_META_UPDATE) { mu = (struct dnet_meta_update *)(data + sizeof(struct dnet_meta)); dnet_convert_meta_update(mu); dnet_current_time(&mu->tm); mu->flags |= flags_set; mu->flags &= ~flags_clear; dnet_convert_meta_update(mu); } data += m.size + sizeof(struct dnet_meta); size -= m.size + sizeof(struct dnet_meta); } return -ENOENT; }
data() : total(0), finished(false) { dnet_current_time(&start); }
elliptics_time elliptics_time::now() { elliptics_time ret; dnet_current_time(&ret.m_time); return ret; }
/*! * Update data-object table for certain secondary index. * * @index_data is what client provided * @data is what was downloaded from the storage */ data_pointer convert_index_table(dnet_node *node, dnet_id *cmd_id, const dnet_indexes_request *request, const data_pointer &index_data, const data_pointer &data, uint32_t action, std::vector<dnet_indexes_reply_entry> * &removed, uint32_t limit) { elliptics_timer timer; dnet_indexes indexes; if (!data.empty()) indexes_unpack(node, cmd_id, data, &indexes, "convert_index_table"); const int64_t timer_unpack = timer.restart(); // Construct index entry dnet_index_entry request_index; memcpy(request_index.index.id, request->id.id, sizeof(request_index.index.id)); request_index.data = index_data; dnet_current_time(&request_index.time); auto it = std::lower_bound(indexes.indexes.begin(), indexes.indexes.end(), request_index, dnet_raw_id_less_than<skip_data>()); const int64_t timer_lower_bound = timer.restart(); if (it != indexes.indexes.end() && it->index == request_index.index) { // It's already there if (action == DNET_INDEXES_FLAGS_INTERNAL_INSERT) { // Item exists, update it's data and time if it's capped collection if (!removed && it->data == request_index.data) { const int64_t timer_compare = timer.restart(); DNET_DUMP_ID_LEN(id_str, cmd_id, DNET_DUMP_NUM); typedef long long int lld; dnet_log(node, DNET_LOG_INFO, "INDEXES_INTERNAL: convert: id: %s, data size: %zu, new data size: %zu," "unpack: %lld ms, lower_bound: %lld ms, compare: %lld ms\n", id_str, data.size(), data.size(), lld(timer_unpack), lld(timer_lower_bound), lld(timer_compare)); // All's ok, keep it untouched return data; } it->data = request_index.data; it->time = request_index.time; } else { // Anyway, destroy it indexes.indexes.erase(it); } } else { // Index is not created yet if (action == DNET_INDEXES_FLAGS_INTERNAL_INSERT) { // Remove extra elements from capped collection if (removed && limit != 0 && indexes.indexes.size() + 1 > limit) { dnet_indexes_reply_entry entry; memset(&entry, 0, sizeof(entry)); auto position = it - indexes.indexes.begin(); while (indexes.indexes.size() + 1 > limit && !indexes.indexes.empty()) { auto jt = std::min_element(indexes.indexes.begin(), indexes.indexes.end(), entry_time_less_than); // jt will be removed, so it should be modified to be still valid if (position > jt - indexes.indexes.begin()) --position; memcpy(entry.id.id, jt->index.id, DNET_ID_SIZE); entry.status = DNET_INDEXES_CAPPED_REMOVED; indexes.indexes.erase(jt); removed->push_back(entry); } it = indexes.indexes.begin() + position; } // And just insert new index indexes.indexes.insert(it, 1, request_index); } else { const int64_t timer_compare = timer.restart(); DNET_DUMP_ID_LEN(id_str, cmd_id, DNET_DUMP_NUM); typedef long long int lld; dnet_log(node, DNET_LOG_INFO, "INDEXES_INTERNAL: convert: id: %s, data size: %zu, new data size: %zu," "unpack: %lld ms, lower_bound: %lld ms, compare: %lld ms\n", id_str, data.size(), data.size(), lld(timer_unpack), lld(timer_lower_bound), lld(timer_compare)); // All's ok, keep it untouched return data; } } const int64_t timer_update = timer.restart(); indexes.shard_id = request->shard_id; indexes.shard_count = request->shard_count; msgpack::sbuffer buffer; msgpack::pack(&buffer, indexes); const int64_t timer_pack = timer.restart(); data_buffer new_buffer(DNET_INDEX_TABLE_MAGIC_SIZE + buffer.size()); new_buffer.write(dnet_bswap64(DNET_INDEX_TABLE_MAGIC)); new_buffer.write(buffer.data(), buffer.size()); const int64_t timer_write = timer.restart(); DNET_DUMP_ID_LEN(id_str, cmd_id, DNET_DUMP_NUM); typedef long long int lld; dnet_log(node, DNET_LOG_INFO, "INDEXES_INTERNAL: convert: id: %s, data size: %zu, new data size: %zu," "unpack: %lld ms, lower_bound: %lld ms, update: %lld ms, pack: %lld ms, write: %lld ms\n", id_str, data.size(), new_buffer.size(), lld(timer_unpack), lld(timer_lower_bound), lld(timer_update), lld(timer_pack), lld(timer_write)); return std::move(new_buffer); }
document() { dnet_current_time(&ts); }