GALib-Parallel
Header-only C++ library for parallel evolutionary algorithms
Loading...
Searching...
No Matches
CircularBuffer.h
Go to the documentation of this file.
1#ifndef CIRCULAR_BUFFER_H
2#define CIRCULAR_BUFFER_H
3
4#pragma once
5
7#include "core/Individual.h"
8#include <iterator>
9#include <vector>
10#include <mutex>
11#include <atomic>
12
13namespace galib::internal {
14 template <typename GeneType>
15 class CircularBuffer : public MigrationBuffer<GeneType> {
16 private:
17 const std::size_t max_batches_m;
18 const std::size_t batch_size_m;
19 std::atomic<std::size_t> filled_batches_m = 0;
20 std::size_t head_batch_m = 0;
21
22 std::vector<std::vector<Individual<GeneType>>> data_m;
23
24 std::mutex mux_m;
25
26 public:
27 explicit CircularBuffer(const std::size_t max_batches, const std::size_t batch_size) : max_batches_m(max_batches),
28 batch_size_m(batch_size),
29 data_m(max_batches) {}
30
31 void push(std::vector<Individual<GeneType>>&& incoming_deme_batch) override {
32 {
33 std::lock_guard<std::mutex> lock(mux_m);
34 data_m[head_batch_m] = std::move(incoming_deme_batch);
35 head_batch_m = (head_batch_m + 1) % max_batches_m;
36
37 if (filled_batches_m < max_batches_m) {
38 ++filled_batches_m;
39 }
40 }
41 }
42
43 virtual void popAll(std::vector<Individual<GeneType>>& target) override {
44 {
45 std::lock_guard<std::mutex> lock(mux_m);
46 target.clear();
47
48 if (filled_batches_m == 0) { return; }
49
50 target.reserve(batch_size_m * filled_batches_m.load());
51
52 for (std::size_t i = 0; i < filled_batches_m; ++i) {
53 head_batch_m = (head_batch_m + max_batches_m - 1) % max_batches_m;
54
55 target.insert(target.end(),
56 std::make_move_iterator(data_m[head_batch_m].begin()),
57 std::make_move_iterator(data_m[head_batch_m].end()));
58
59 data_m[head_batch_m].clear();
60 }
61
62 filled_batches_m.store(0);
63 }
64 }
65
66 [[nodiscard]] bool hasMigrants() const override {
67 return filled_batches_m.load() > 0;
68 }
69 };
70}
71
72#endif // CIRCULAR_BUFFER_H
Represents a single candidate solution in the population.
Definition Individual.h:23
bool hasMigrants() const override
Checks if there are any migrants waiting in the buffer.
CircularBuffer(const std::size_t max_batches, const std::size_t batch_size)
void push(std::vector< Individual< GeneType > > &&incoming_deme_batch) override
Adds a batch of individuals to the buffer.
virtual void popAll(std::vector< Individual< GeneType > > &target) override
Retrieves and removes all currently stored migrants.
Interface for a thread-safe buffer that stores incoming migrants.