| 1211 | } |
| 1212 | |
| 1213 | bool buffer::list::rebuild_aligned_size_and_memory(unsigned align_size, |
| 1214 | unsigned align_memory, |
| 1215 | unsigned max_buffers) |
| 1216 | { |
| 1217 | bool had_to_rebuild = false; |
| 1218 | |
| 1219 | if (max_buffers && _num > max_buffers && _len > (max_buffers * align_size)) { |
| 1220 | align_size = round_up_to(round_up_to(_len, max_buffers) / max_buffers, align_size); |
| 1221 | } |
| 1222 | auto p = std::begin(_buffers); |
| 1223 | auto p_prev = _buffers.before_begin(); |
| 1224 | while (p != std::end(_buffers)) { |
| 1225 | // keep anything that's already align and sized aligned |
| 1226 | if (p->is_aligned(align_memory) && p->is_n_align_sized(align_size)) { |
| 1227 | /*cout << " segment " << (void*)p->c_str() |
| 1228 | << " offset " << ((unsigned long)p->c_str() & (align - 1)) |
| 1229 | << " length " << p->length() |
| 1230 | << " " << (p->length() & (align - 1)) << " ok" << std::endl; |
| 1231 | */ |
| 1232 | p_prev = p++; |
| 1233 | continue; |
| 1234 | } |
| 1235 | |
| 1236 | // consolidate unaligned items, until we get something that is sized+aligned |
| 1237 | list unaligned; |
| 1238 | unsigned offset = 0; |
| 1239 | do { |
| 1240 | /*cout << " segment " << (void*)p->c_str() |
| 1241 | << " offset " << ((unsigned long)p->c_str() & (align - 1)) |
| 1242 | << " length " << p->length() << " " << (p->length() & (align - 1)) |
| 1243 | << " overall offset " << offset << " " << (offset & (align - 1)) |
| 1244 | << " not ok" << std::endl; |
| 1245 | */ |
| 1246 | offset += p->length(); |
| 1247 | // no need to reallocate, relinking is enough thankfully to bi::list. |
| 1248 | auto p_after = _buffers.erase_after(p_prev); |
| 1249 | _num -= 1; |
| 1250 | unaligned._buffers.push_back(*p); |
| 1251 | unaligned._len += p->length(); |
| 1252 | unaligned._num += 1; |
| 1253 | p = p_after; |
| 1254 | } while (p != std::end(_buffers) && |
| 1255 | (!p->is_aligned(align_memory) || |
| 1256 | !p->is_n_align_sized(align_size) || |
| 1257 | (offset % align_size))); |
| 1258 | if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align_memory))) { |
| 1259 | unaligned.rebuild( |
| 1260 | ptr_node::create( |
| 1261 | buffer::create_aligned(unaligned._len, align_memory))); |
| 1262 | had_to_rebuild = true; |
| 1263 | } |
| 1264 | if (unaligned.get_num_buffers()) { |
| 1265 | _buffers.insert_after(p_prev, *ptr_node::create(unaligned._buffers.front()).release()); |
| 1266 | _num += 1; |
| 1267 | } else { |
| 1268 | // a bufferlist containing only 0-length bptrs is rebuilt as empty |
| 1269 | } |
| 1270 | ++p_prev; |