-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathshuffle.cc
61 lines (52 loc) · 1.54 KB
/
shuffle.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <cassert>
#include <cstdlib>
#include <numeric>
#include <random>
#include <string>
#include <vector>
#include "shuffle.h"
namespace ashuffle {
void ShuffleChain::Clear() {
_window.clear();
_pool.clear();
_items.clear();
}
void ShuffleChain::Add(ShuffleItem item) {
_items.emplace_back(item);
_pool.push_back(_items.size() - 1);
}
size_t ShuffleChain::Len() const { return _items.size(); }
size_t ShuffleChain::LenURIs() const {
size_t sum = 0;
for (auto& group : _items) {
sum += group._uris.size();
}
return sum;
}
/* ensure that our window is as full as it can possibly be. */
void ShuffleChain::FillWindow() {
while (_window.size() <= _max_window && _pool.size() > 0) {
std::uniform_int_distribution<unsigned long long> rd{0,
_pool.size() - 1};
/* push a random song from the pool onto the end of the window */
size_t idx = rd(_rng);
_window.push_back(_pool[idx]);
_pool.erase(_pool.begin() + idx);
}
}
const std::vector<std::string>& ShuffleChain::Pick() {
assert(Len() != 0 && "cannot pick from empty chain");
FillWindow();
size_t picked_idx = _window[0];
_window.pop_front();
_pool.push_back(picked_idx);
return _items[picked_idx]._uris;
}
std::vector<std::vector<std::string>> ShuffleChain::Items() {
std::vector<std::vector<std::string>> result;
for (auto group : _items) {
result.push_back(group._uris);
}
return result;
}
} // namespace ashuffle