#include "assert.h"
#include "encoding_btree.h"
-template<typename T>
+template<typename T,
+ typename Alloc = std::allocator<std::pair<const T, T>>>
class btree_interval_set {
public:
- typedef btree::btree_map<T,T> map_t;
+ typedef btree::btree_map<T,T, std::less<T>, Alloc> map_t;
class const_iterator;
return m.size();
}
- typename btree_interval_set<T>::iterator begin() {
- return typename btree_interval_set<T>::iterator(m.begin());
+ typename btree_interval_set<T,Alloc>::iterator begin() {
+ return typename btree_interval_set<T,Alloc>::iterator(m.begin());
}
- typename btree_interval_set<T>::iterator lower_bound(T start) {
- return typename btree_interval_set<T>::iterator(find_inc_m(start));
+ typename btree_interval_set<T,Alloc>::iterator lower_bound(T start) {
+ return typename btree_interval_set<T,Alloc>::iterator(find_inc_m(start));
}
- typename btree_interval_set<T>::iterator end() {
- return typename btree_interval_set<T>::iterator(m.end());
+ typename btree_interval_set<T,Alloc>::iterator end() {
+ return typename btree_interval_set<T,Alloc>::iterator(m.end());
}
- typename btree_interval_set<T>::const_iterator begin() const {
- return typename btree_interval_set<T>::const_iterator(m.begin());
+ typename btree_interval_set<T,Alloc>::const_iterator begin() const {
+ return typename btree_interval_set<T,Alloc>::const_iterator(m.begin());
}
- typename btree_interval_set<T>::const_iterator lower_bound(T start) const {
- return typename btree_interval_set<T>::const_iterator(find_inc(start));
+ typename btree_interval_set<T,Alloc>::const_iterator lower_bound(T start) const {
+ return typename btree_interval_set<T,Alloc>::const_iterator(find_inc(start));
}
- typename btree_interval_set<T>::const_iterator end() const {
- return typename btree_interval_set<T>::const_iterator(m.end());
+ typename btree_interval_set<T,Alloc>::const_iterator end() const {
+ return typename btree_interval_set<T,Alloc>::const_iterator(m.end());
}
// helpers
};
-template<class T>
-inline std::ostream& operator<<(std::ostream& out, const btree_interval_set<T> &s) {
+template<class T, class A>
+inline std::ostream& operator<<(std::ostream& out, const btree_interval_set<T,A> &s) {
out << "[";
const char *prequel = "";
- for (typename btree_interval_set<T>::const_iterator i = s.begin();
+ for (auto i = s.begin();
i != s.end();
++i)
{
return out;
}
-template<class T>
-inline void encode(const btree_interval_set<T>& s, bufferlist& bl)
+template<class T,typename A>
+inline void encode(const btree_interval_set<T,A>& s, bufferlist& bl)
{
s.encode(bl);
}
-template<class T>
-inline void decode(btree_interval_set<T>& s, bufferlist::iterator& p)
+template<class T,typename A>
+inline void decode(btree_interval_set<T,A>& s, bufferlist::iterator& p)
{
s.decode(p);
}
}
/// return the effective length of the extent if we align to alloc_unit
-static uint64_t aligned_len(btree_interval_set<uint64_t>::iterator p,
- uint64_t alloc_unit)
+uint64_t StupidAllocator::_aligned_len(
+ btree_interval_set<uint64_t,allocator>::iterator p,
+ uint64_t alloc_unit)
{
uint64_t skew = p.get_start() % alloc_unit;
if (skew)
for (bin = orig_bin; bin < (int)free.size(); ++bin) {
p = free[bin].lower_bound(hint);
while (p != free[bin].end()) {
- if (aligned_len(p, alloc_unit) >= want_size) {
+ if (_aligned_len(p, alloc_unit) >= want_size) {
goto found;
}
++p;
p = free[bin].begin();
auto end = hint ? free[bin].lower_bound(hint) : free[bin].end();
while (p != end) {
- if (aligned_len(p, alloc_unit) >= want_size) {
+ if (_aligned_len(p, alloc_unit) >= want_size) {
goto found;
}
++p;
for (bin = orig_bin; bin >= 0; --bin) {
p = free[bin].lower_bound(hint);
while (p != free[bin].end()) {
- if (aligned_len(p, alloc_unit) >= alloc_unit) {
+ if (_aligned_len(p, alloc_unit) >= alloc_unit) {
goto found;
}
++p;
p = free[bin].begin();
auto end = hint ? free[bin].lower_bound(hint) : free[bin].end();
while (p != end) {
- if (aligned_len(p, alloc_unit) >= alloc_unit) {
+ if (_aligned_len(p, alloc_unit) >= alloc_unit) {
goto found;
}
++p;
std::lock_guard<std::mutex> l(lock);
dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
<< std::dec << dendl;
- btree_interval_set<uint64_t> rm;
+ btree_interval_set<uint64_t,allocator> rm;
rm.insert(offset, length);
for (unsigned i = 0; i < free.size() && !rm.empty(); ++i) {
- btree_interval_set<uint64_t> overlap;
+ btree_interval_set<uint64_t,allocator> overlap;
overlap.intersection_of(rm, free[i]);
if (!overlap.empty()) {
dout(20) << __func__ << " bin " << i << " rm 0x" << std::hex << overlap
#include "Allocator.h"
#include "include/btree_interval_set.h"
#include "os/bluestore/bluestore_types.h"
+#include "include/mempool.h"
class StupidAllocator : public Allocator {
CephContext* cct;
int64_t num_free; ///< total bytes in freelist
int64_t num_reserved; ///< reserved bytes
- std::vector<btree_interval_set<uint64_t> > free; ///< leading-edge copy
+ typedef mempool::bluestore_alloc::pool_allocator<
+ pair<const uint64_t,uint64_t>> allocator;
+ std::vector<btree_interval_set<uint64_t,allocator>> free; ///< leading-edge copy
uint64_t last_alloc;
unsigned _choose_bin(uint64_t len);
void _insert_free(uint64_t offset, uint64_t len);
+ uint64_t _aligned_len(
+ btree_interval_set<uint64_t,allocator>::iterator p,
+ uint64_t alloc_unit);
+
public:
StupidAllocator(CephContext* cct);
~StupidAllocator() override;