diff options
Diffstat (limited to 'src/test/osd/Object.cc')
-rw-r--r-- | src/test/osd/Object.cc | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/src/test/osd/Object.cc b/src/test/osd/Object.cc new file mode 100644 index 000000000..9d914abd7 --- /dev/null +++ b/src/test/osd/Object.cc @@ -0,0 +1,200 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +#include "include/interval_set.h" +#include "include/buffer.h" +#include <list> +#include <map> +#include <set> +#include <iostream> + +#include "Object.h" + +void ContDesc::encode(bufferlist &bl) const +{ + ENCODE_START(1, 1, bl); + encode(objnum, bl); + encode(cursnap, bl); + encode(seqnum, bl); + encode(prefix, bl); + encode(oid, bl); + ENCODE_FINISH(bl); +} + +void ContDesc::decode(bufferlist::const_iterator &bl) +{ + DECODE_START(1, bl); + decode(objnum, bl); + decode(cursnap, bl); + decode(seqnum, bl); + decode(prefix, bl); + decode(oid, bl); + DECODE_FINISH(bl); +} + +std::ostream &operator<<(std::ostream &out, const ContDesc &rhs) +{ + return out << "(ObjNum " << rhs.objnum + << " snap " << rhs.cursnap + << " seq_num " << rhs.seqnum + << ")"; +} + +void AppendGenerator::get_ranges_map( + const ContDesc &cont, std::map<uint64_t, uint64_t> &out) { + RandWrap rand(cont.seqnum); + uint64_t pos = off; + uint64_t limit = off + get_append_size(cont); + while (pos < limit) { + uint64_t segment_length = round_up( + rand() % (max_append_size - min_append_size), + alignment) + min_append_size; + ceph_assert(segment_length >= min_append_size); + if (segment_length + pos > limit) { + segment_length = limit - pos; + } + if (alignment) + ceph_assert(segment_length % alignment == 0); + out.insert(std::pair<uint64_t, uint64_t>(pos, segment_length)); + pos += segment_length; + } +} + +void VarLenGenerator::get_ranges_map( + const ContDesc &cont, std::map<uint64_t, uint64_t> &out) { + RandWrap rand(cont.seqnum); + uint64_t pos = 0; + uint64_t limit = get_length(cont); + bool include = false; + while (pos < limit) { + uint64_t segment_length = (rand() % (max_stride_size - min_stride_size)) + min_stride_size; + ceph_assert(segment_length < max_stride_size); + ceph_assert(segment_length >= min_stride_size); + if (segment_length + pos > limit) { + segment_length = limit - pos; + } + if (include) { + out.insert(std::pair<uint64_t, uint64_t>(pos, segment_length)); + include = false; + } else { + include = true; + } + pos += segment_length; + } +} + +void ObjectDesc::iterator::adjust_stack() { + while (!stack.empty() && pos >= stack.top().second.next) { + ceph_assert(pos == stack.top().second.next); + size = stack.top().second.size; + current = stack.top().first; + stack.pop(); + } + + if (stack.empty()) { + cur_valid_till = std::numeric_limits<uint64_t>::max(); + } else { + cur_valid_till = stack.top().second.next; + } + + while (current != layers.end() && !current->covers(pos)) { + uint64_t next = current->next(pos); + if (next < cur_valid_till) { + stack.emplace(current, StackState{next, size}); + cur_valid_till = next; + } + + ++current; + } + + if (current == layers.end()) { + size = 0; + } else { + current->iter.seek(pos); + size = std::min(size, current->get_size()); + cur_valid_till = std::min( + current->valid_till(pos), + cur_valid_till); + } +} + +const ContDesc &ObjectDesc::most_recent() { + return layers.begin()->second; +} + +void ObjectDesc::update(ContentsGenerator *gen, const ContDesc &next) { + layers.push_front(std::pair<std::shared_ptr<ContentsGenerator>, ContDesc>(std::shared_ptr<ContentsGenerator>(gen), next)); + return; +} + +bool ObjectDesc::check(bufferlist &to_check) { + iterator objiter = begin(); + uint64_t error_at = 0; + if (!objiter.check_bl_advance(to_check, &error_at)) { + std::cout << "incorrect buffer at pos " << error_at << std::endl; + return false; + } + + uint64_t size = layers.begin()->first->get_length(layers.begin()->second); + if (to_check.length() < size) { + std::cout << "only read " << to_check.length() + << " out of size " << size << std::endl; + return false; + } + return true; +} + +bool ObjectDesc::check_sparse(const std::map<uint64_t, uint64_t>& extents, + bufferlist &to_check) +{ + uint64_t off = 0; + uint64_t pos = 0; + auto objiter = begin(); + for (auto &&extiter : extents) { + // verify hole + { + bufferlist bl; + bl.append_zero(extiter.first - pos); + uint64_t error_at = 0; + if (!objiter.check_bl_advance(bl, &error_at)) { + std::cout << "sparse read omitted non-zero data at " + << error_at << std::endl; + return false; + } + } + + ceph_assert(off <= to_check.length()); + pos = extiter.first; + objiter.seek(pos); + + { + bufferlist bl; + bl.substr_of( + to_check, + off, + std::min(to_check.length() - off, extiter.second)); + uint64_t error_at = 0; + if (!objiter.check_bl_advance(bl, &error_at)) { + std::cout << "incorrect buffer at pos " << error_at << std::endl; + return false; + } + off += extiter.second; + pos += extiter.second; + } + + if (pos < extiter.first + extiter.second) { + std::cout << "reached end of iterator first" << std::endl; + return false; + } + } + + // final hole + bufferlist bl; + uint64_t size = layers.begin()->first->get_length(layers.begin()->second); + bl.append_zero(size - pos); + uint64_t error_at; + if (!objiter.check_bl_advance(bl, &error_at)) { + std::cout << "sparse read omitted non-zero data at " + << error_at << std::endl; + return false; + } + return true; +} |