From 4b5e2d6c4097f8e08f3ef47a6f0e4212a0eaf795 Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Thu, 14 Jul 2016 19:21:32 +0800 Subject: [PATCH] os/bluestore: use map to tracking writing buffers By keeping the writing buffers ordered, the finish_write() process does not need to traverse the whole writing list each time it is called any more, which is good for performance. Signed-off-by: xie xingguo --- src/os/bluestore/BlueStore.cc | 34 +++++++++++++++++++++------------- src/os/bluestore/BlueStore.h | 13 +++++++++---- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 74df5b9234925..bc8bbf8997b69 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -1016,24 +1016,32 @@ void BlueStore::BufferSpace::read( void BlueStore::BufferSpace::finish_write(uint64_t seq) { std::lock_guard l(cache->lock); - auto i = writing.begin(); - while (i != writing.end()) { - Buffer *b = &*i; - dout(20) << __func__ << " " << *b << dendl; - assert(b->is_writing()); - if (b->seq <= seq) { + + auto i = writing_map.begin(); + while (i != writing_map.end()) { + if (i->first > seq) + break; + + auto l = i->second.begin(); + while (l != i->second.end()) { + Buffer *b = &*l; + dout(20) << __func__ << " " << *b << dendl; + assert(b->is_writing()); + if (b->flags & Buffer::FLAG_NOCACHE) { - ++i; - _rm_buffer(b); + i->second.erase(l++); + buffer_map.erase(b->offset); } else { - b->state = Buffer::STATE_CLEAN; - writing.erase(i++); - cache->_add_buffer(b, 1, nullptr); + b->state = Buffer::STATE_CLEAN; + i->second.erase(l++); + cache->_add_buffer(b, 1, nullptr); } - } else { - ++i; } + + assert(i->second.empty()); + writing_map.erase(i++); } + cache->_audit("finish_write end"); } diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 9a3b7b1017cb5..200adcd038025 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -199,19 +199,19 @@ public: map> buffer_map; Cache *cache; - state_list_t writing; + map writing_map; BufferSpace(Cache *c) : cache(c) {} ~BufferSpace() { assert(buffer_map.empty()); - assert(writing.empty()); + assert(writing_map.empty()); } void _add_buffer(Buffer *b, int level, Buffer *near) { cache->_audit("_add_buffer start"); buffer_map[b->offset].reset(b); if (b->is_writing()) { - writing.push_back(*b); + writing_map[b->seq].push_back(*b); } else { cache->_add_buffer(b, level, near); } @@ -223,7 +223,12 @@ public: void _rm_buffer(map>::iterator p) { cache->_audit("_rm_buffer start"); if (p->second->is_writing()) { - writing.erase(writing.iterator_to(*p->second)); + uint64_t seq = (*p->second.get()).seq; + auto it = writing_map.find(seq); + assert(it != writing_map.end()); + it->second.erase(it->second.iterator_to(*p->second)); + if (it->second.empty()) + writing_map.erase(it); } else { cache->_rm_buffer(p->second.get()); } -- 2.39.5