-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.cpp
More file actions
95 lines (71 loc) · 2.16 KB
/
database.cpp
File metadata and controls
95 lines (71 loc) · 2.16 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "database.h"
#include <algorithm>
#include <sstream>
#include <stack>
void Database::Add(const Date& date, const string& event) {
if (presence.count(date) && presence[date].count(event)) {
return;
}
storage[date].push_back(event);
presence[date].insert(event);
}
void Database::Print(ostream& out_stream) const {
for (const auto& [date, ev_queue] : storage) {
for (const string& event : ev_queue) {
out_stream << date << " " << event << endl;
}
}
}
int Database::RemoveIf(Predicate pred) {
int count = 0;
stack<Date> to_pop;
for (auto& kv : storage) {
auto& date = kv.first;
auto& ev_queue = kv.second;
auto it = stable_partition(ev_queue.begin(), ev_queue.end(), [&date, &pred](const string& event) {
return !pred(date, event);
});
count += ev_queue.end() - it;
for_each(it, ev_queue.end(), [this, &date](const string& event) {
presence[date].erase(event);
});
ev_queue.erase(it, ev_queue.end());
if (ev_queue.empty()) {
to_pop.push(date);
}
}
while (!to_pop.empty()) {
const Date& date = to_pop.top();
storage.erase(date);
presence.erase(date);
to_pop.pop();
}
return count;
}
vector<string> Database::FindIf(Predicate pred) const {
vector<string> result;
for (const auto& kv : storage) {
const auto& date = kv.first;
const auto& ev_queue = kv.second;
for_each(ev_queue.begin(), ev_queue.end(), [&pred, &result, &date](const string& event) {
if (pred(date, event)) {
ostringstream fmt;
fmt << date << ' ' << event;
result.push_back(fmt.str());
}
});
}
return result;
}
string Database::Last(const Date& date) const {
if (storage.empty() || storage.begin()->first > date) {
return "No entries";
}
auto it = storage.lower_bound(date);
if (it == storage.end() || it->first > date) {
--it;
}
ostringstream fmt;
fmt << it->first << ' ' << it->second.back();
return fmt.str();
}