return o->read(offset, l, bl);
}
-
int MemStore::fiemap(coll_t cid, const ghobject_t& oid,
uint64_t offset, size_t len, bufferlist& bl)
{
}
// PageSetObject
+
+// use a thread-local vector for the pages returned by PageSet, so we
+// can avoid allocations in read/write()
+thread_local PageSet::page_vector MemStore::PageSetObject::tls_pages;
+
int MemStore::PageSetObject::read(uint64_t offset, uint64_t len, bufferlist& bl)
{
const auto start = offset;
const auto end = offset + len;
auto remaining = len;
- PageSet::page_vector pages;
- data.get_range(offset, len, pages);
+ data.get_range(offset, len, tls_pages);
// allocate a buffer for the data
buffer::ptr buf(len);
- auto p = pages.begin();
+ auto p = tls_pages.begin();
while (remaining) {
// no more pages in range
- if (p == pages.end() || (*p)->offset >= end) {
+ if (p == tls_pages.end() || (*p)->offset >= end) {
buf.zero(offset - start, remaining);
break;
}
++p;
}
+ tls_pages.clear(); // drop page refs
+
bl.append(buf);
return len;
}
unsigned len = src.length();
// make sure the page range is allocated
- PageSet::page_vector pages;
- data.alloc_range(offset, src.length(), pages);
+ data.alloc_range(offset, src.length(), tls_pages);
- auto page = pages.begin();
+ auto page = tls_pages.begin();
// XXX: cast away the const because bufferlist doesn't have a const_iterator
auto p = const_cast<bufferlist&>(src).begin();
}
if (data_len < offset)
data_len = offset;
+ tls_pages.clear(); // drop page refs
return 0;
}
auto &dst_data = data;
const auto dst_page_size = dst_data.get_page_size();
- PageSet::page_vector src_pages, dst_pages;
+ PageSet::page_vector dst_pages;
while (len) {
const auto count = std::min(len, src_page_size * 16);
- src_data.get_range(srcoff, count, src_pages);
+ src_data.get_range(srcoff, count, tls_pages);
- for (auto &src_page : src_pages) {
+ for (auto &src_page : tls_pages) {
auto sbegin = std::max(srcoff, src_page->offset);
auto send = std::min(srcoff + count, src_page->offset + src_page_size);
dst_data.alloc_range(sbegin + delta, send - sbegin, dst_pages);
dstoff += count;
len -= count;
}
- src_pages.clear(); // drop page refs
+ tls_pages.clear(); // drop page refs
}
// update object size
return 0;
// write zeroes to the rest of the last page
- PageSet::page_vector pages;
- data.get_range(page_offset, page_size, pages);
- if (pages.empty())
+ data.get_range(page_offset, page_size, tls_pages);
+ if (tls_pages.empty())
return 0;
- auto page = pages.begin();
+ auto page = tls_pages.begin();
auto data = (*page)->data;
std::fill(data + (size - page_offset), data + page_size, 0);
+ tls_pages.clear(); // drop page ref
return 0;
}