From 3c2024de44735657dac690665540778f5a7e3e6e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 2 Oct 2012 14:44:54 -0700 Subject: [PATCH] filer: helper to assemble striped read results into a single result This is intended to replace the Objecter::_sg_read_finish() monstrosity, and be reused by the librbd striping code. Signed-off-by: Sage Weil --- src/osdc/Filer.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/osdc/Filer.h b/src/osdc/Filer.h index a9ad5ee9333c7..237f618458c8d 100644 --- a/src/osdc/Filer.h +++ b/src/osdc/Filer.h @@ -124,6 +124,56 @@ class Filer { uint64_t objectno, uint64_t off, uint64_t len, vector >& extents); + /* + * helper to assemble a striped result + */ + class StripedReadResult { + map > partial; // offset -> (data, intended length) + + public: + void add_partial_result(bufferlist& bl, + const vector >& buffer_extents) { + for (vector >::const_iterator p = buffer_extents.begin(); + p != buffer_extents.end(); + ++p) { + pair& r = partial[p->first]; + size_t actual = MIN(bl.length(), p->second); + bl.splice(0, actual, &r.first); + r.second = p->second; + } + } + + void assemble_result(bufferlist& bl) { + // go backwards, so that we can efficiently discard zeros + map >::reverse_iterator p = partial.rbegin(); + if (p == partial.rend()) + return; + + uint64_t end = p->first + p->second.second; + while (p != partial.rend()) { + // sanity check + assert(p->first == end - p->second.second); + end = p->first; + + size_t len = p->second.first.length(); + if (len < p->second.second) { + if (bl.length()) { + bufferptr bp(p->second.second - p->second.first.length()); + bp.zero(); + bl.push_front(bp); + bl.claim_prepend(p->second.first); + } else { + bl.claim_prepend(p->second.first); + } + } else { + bl.claim_prepend(p->second.first); + } + p++; + } + partial.clear(); + } + }; + /*** async file interface. scatter/gather as needed. ***/ -- 2.39.5