blob: 19b7b85d5103f462345f5975db2754dd1c8bfbcd (
plain) (
blame)
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
|
#include "split.h"
#include <util/generic/list.h>
#include <util/generic/vector.h>
namespace NIPREG {
void SplitIPREG(TReader &reader, std::function<void(const TAddress& first, const TAddress& last, const TVector<TString>& data)>&& proc) {
TList<TGenericEntry> prevEntries;
bool end;
do {
end = !reader.Next();
while (!prevEntries.empty() && (end || prevEntries.front().First < reader.Get().First)) {
// find smallest common range to process
TAddress first = prevEntries.front().First;
TAddress last = end ? TAddress::Highest() : reader.Get().First.Prev();
for (const auto& entry: prevEntries)
last = Min(last, entry.Last);
// extract data for the range
TVector<TString> strings;
auto item = prevEntries.begin();
while (item != prevEntries.end()) {
Y_ASSERT(item->First == first);
strings.push_back(item->Data);
if (item->Last == last) {
// item completely processed, remove
auto victim = item;
item++;
prevEntries.erase(victim);
} else {
// item still have part of range left, update it
item->First = last.Next();
item++;
}
}
proc(first, last, strings);
}
if (!end) {
if (!prevEntries.empty()) {
Y_ASSERT(prevEntries.front().First == reader.Get().First);
}
prevEntries.push_back(reader.Get());
}
} while (!end);
}
}
|