205 my_oracle(std::move(oracle)),
206 my_total(my_oracle->total()),
207 my_max_slabs(sanisizer::cast<I<decltype(my_max_slabs)> >(max_slabs))
209 my_all_slabs.reserve(max_slabs);
210 my_current_cache.reserve(max_slabs);
211 my_future_cache.reserve(max_slabs);
212 my_close_future_subset_cache.reserve(max_slabs);
213 my_far_future_subset_cache.reserve(max_slabs);
215 my_all_subset_details.resize(sanisizer::product<I<
decltype(my_all_subset_details.size())> >(2, max_slabs));
216 for (
auto& as : my_all_subset_details) {
217 my_free_subset_details.push_back(&as);
284 std::pair<const Slab_*, Index_>
next(Ifunction_ identify, Cfunction_ create, Pfunction_ populate) {
285 Index_ index = this->
next();
286 auto slab_info = identify(index);
287 if (slab_info.first == my_last_slab_id && my_last_slab) {
288 return std::make_pair(my_last_slab, slab_info.second);
290 my_last_slab_id = slab_info.first;
293 if (my_counter - 1 == my_close_refresh_point) {
294 if (my_all_slabs.empty()) {
296 requisition_subset_close(slab_info.first, slab_info.second);
297 I<
decltype(my_max_slabs)> used_slabs = 1;
299 while (++my_close_refresh_point < my_total) {
300 auto future_index = my_oracle->get(my_close_refresh_point);
301 auto future_slab_info = identify(future_index);
302 auto cfcIt = my_close_future_subset_cache.find(future_slab_info.first);
303 if (cfcIt != my_close_future_subset_cache.end()) {
304 OracularSubsettedSlabCache_internals::add_to_details(*(cfcIt->second), future_slab_info.second);
305 }
else if (used_slabs < my_max_slabs) {
306 requisition_subset_close(future_slab_info.first, future_slab_info.second);
309 my_far_slab_id = future_slab_info.first;
310 my_far_slab_offset = future_slab_info.second;
315 my_far_refresh_point = my_close_refresh_point;
317 my_close_refresh_point = my_far_refresh_point;
321 if (my_far_refresh_point < my_total) {
322 requisition_subset_far(my_far_slab_id, my_far_slab_offset);
323 I<
decltype(my_max_slabs)> used_slabs = 1;
325 while (++my_far_refresh_point < my_total) {
326 auto future_index = my_oracle->get(my_far_refresh_point);
327 auto future_slab_info = identify(future_index);
328 auto ffcIt = my_far_future_subset_cache.find(future_slab_info.first);
329 if (ffcIt != my_far_future_subset_cache.end()) {
330 OracularSubsettedSlabCache_internals::add_to_details(*(ffcIt->second), future_slab_info.second);
331 }
else if (used_slabs < my_max_slabs) {
332 requisition_subset_far(future_slab_info.first, future_slab_info.second);
335 my_far_slab_id = future_slab_info.first;
336 my_far_slab_offset = future_slab_info.second;
343 for (
auto& cf : my_close_future_subset_cache) {
344 auto cIt = my_current_cache.find(cf.first);
345 if (cIt == my_current_cache.end()) {
346 my_to_reassign.emplace_back(cf.first, cf.second);
348 my_future_cache[cf.first] = cIt->second;
349 my_current_cache.erase(cIt);
354 auto cIt = my_current_cache.begin();
355 for (
auto a : my_to_reassign) {
357 if (cIt == my_current_cache.end()) {
358 my_all_slabs.emplace_back(create());
359 slab_ptr = &(my_all_slabs.back());
361 slab_ptr = cIt->second;
364 my_future_cache[a.first] = slab_ptr;
365 OracularSubsettedSlabCache_internals::finalize_details(*(a.second));
366 my_to_populate.emplace_back(a.first, slab_ptr, a.second);
368 my_to_reassign.clear();
370 populate(my_to_populate);
371 my_to_populate.clear();
381 my_current_cache.clear();
382 my_current_cache.swap(my_future_cache);
386 for (
auto& cfc : my_close_future_subset_cache) {
387 my_free_subset_details.push_back(cfc.second);
389 my_close_future_subset_cache.clear();
390 my_close_future_subset_cache.swap(my_far_future_subset_cache);
394 auto ccIt = my_current_cache.find(slab_info.first);
395 my_last_slab = ccIt->second;
396 return std::make_pair(my_last_slab, slab_info.second);