summaryrefslogtreecommitdiffstats
path: root/library/cpp/ipreg/split.cpp
diff options
context:
space:
mode:
authorvvvv <[email protected]>2023-07-31 18:21:04 +0300
committervvvv <[email protected]>2023-07-31 18:21:04 +0300
commitdec41c40e51aa407edef81a3c566a5a15780fc49 (patch)
tree4f197b596b32f35eca368121f0dff913419da9af /library/cpp/ipreg/split.cpp
parent3ca8b54c96e09eb2b65be7f09675623438d559c7 (diff)
YQL-16239 Move purecalc to public
Diffstat (limited to 'library/cpp/ipreg/split.cpp')
-rw-r--r--library/cpp/ipreg/split.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/library/cpp/ipreg/split.cpp b/library/cpp/ipreg/split.cpp
new file mode 100644
index 00000000000..19b7b85d510
--- /dev/null
+++ b/library/cpp/ipreg/split.cpp
@@ -0,0 +1,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);
+}
+
+}