4#include "SwathPathChunks.h"
5#include "SwathPathResamplingPositions.h"
8#define VERBOSE_WRAP(a) do ; while(0)
12 const std::string
package = "SwathPathChunks: ";
16Cogs::Core::EchoSounder::SwathPathChunks::SwathPathChunks(uint32_t preferredExtent, uint32_t skirtSize)
17 : preferredExtent(preferredExtent),
22void Cogs::Core::EchoSounder::SwathPathChunks::clear()
26 VERBOSE_WRAP(std::cerr << package <<
"Clear\n");
29bool Cogs::Core::EchoSounder::SwathPathChunks::retireEvictedPositions(
const SwathPathResamplingPositions& positions)
32 const auto & entries = positions.getEntries();
34 while (!chunks.empty() && !entries.validIndex(chunks.front().support.a)) {
35 VERBOSE_WRAP(std::cerr << package <<
"Popped chunk " << chunks.frontIndex() <<
" [" << chunks.front().support.a <<
", " << chunks.front().support.b <<
"]\n");
43bool Cogs::Core::EchoSounder::SwathPathChunks::seedIfQueueEmpty(
const SwathPathResamplingPositions& positions)
45 if (!chunks.empty())
return false;
47 const auto leastRecentIndex = positions.getEntries().frontIndex();
48 const auto mostRecentIndex = positions.getEntries().backIndex();
50 uint32_t m = mostRecentIndex - leastRecentIndex;
53 chunk.extent.b = mostRecentIndex;
54 chunk.extent.a = mostRecentIndex - std::min(preferredExtent, m);
55 chunk.support.b = mostRecentIndex;
56 chunk.support.a = mostRecentIndex - std::min(preferredExtent + skirtSize, m);
57 assert(chunk.extent.a - chunk.support.a <= chunk.support.b - chunk.support.a);
58 assert(chunk.extent.b - chunk.support.a <= chunk.support.b - chunk.support.a);
60 chunks.pushBack(chunk);
61 VERBOSE_WRAP(std::cerr << package <<
"seed: " <<
62 chunks.back().support.a <<
"/" << chunks.back().extent.a <<
"..." <<
63 chunks.back().extent.b <<
"/" << chunks.back().support.b <<
" [" << leastRecentIndex <<
":" << mostRecentIndex <<
"\n");
70bool Cogs::Core::EchoSounder::SwathPathChunks::tryGrowMoreRecent(
const SwathPathResamplingPositions& positions)
72 if (chunks.empty())
return false;
74 const auto & entries = positions.getEntries();
75 const auto leastRecentIndex = entries.frontIndex();
76 const auto mostRecentIndex = entries.backIndex();
78 if (chunks.back().extent.b == mostRecentIndex)
return false;
84 auto & c = chunks.back();
86 auto extent_b = c.extent.a + std::min(preferredExtent, mostRecentIndex - c.extent.a);
87 auto support_b = c.extent.a + std::min(preferredExtent + skirtSize, mostRecentIndex - c.extent.a);
88 rv = rv || (c.extent.b != extent_b) || (c.support.b != support_b);
89 c.extent.b = extent_b;
90 c.support.b = support_b;
92 assert(c.extent.a - c.support.a <= c.support.b - c.support.a);
93 assert(c.extent.b - c.support.a <= c.support.b - c.support.a);
98 for (uint32_t i = 0; i < chunks.count(); i++) {
99 auto & c = chunks[chunks.frontIndex() + i];
100 if (c.support.b - c.extent.b < skirtSize) {
101 auto support_b = c.extent.b + std::min(skirtSize, mostRecentIndex - c.extent.b);
102 rv = rv || (c.support.b != support_b);
103 c.support.b = support_b;
105 assert(c.extent.a - c.support.a <= c.support.b - c.support.a);
106 assert(c.extent.b - c.support.a <= c.support.b - c.support.a);
111 while (
static_cast<int32_t
>(mostRecentIndex - chunks.back().extent.b) > 0) {
113 SwathPathChunk chunk;
114 chunk.extent.a = chunks.back().extent.b;
115 chunk.support.a = chunk.extent.a - std::min(skirtSize, chunk.extent.a - leastRecentIndex);
117 chunk.extent.b = chunk.extent.a + std::min(preferredExtent, mostRecentIndex - chunk.extent.a);
118 chunk.support.b = chunk.extent.b + std::min(skirtSize, mostRecentIndex - chunk.extent.b);
120 chunk.flags = SwathPathChunkFlag::None;
122 assert(chunk.extent.a - chunk.support.a <= chunk.support.b - chunk.support.a);
123 assert(chunk.extent.b - chunk.support.a <= chunk.support.b - chunk.support.a);
126 assert(
static_cast<int32_t
>(mostRecentIndex - chunk.extent.b) <
static_cast<int32_t
>(mostRecentIndex - chunks.back().extent.b));
128 chunks.pushBack(chunk);
135bool Cogs::Core::EchoSounder::SwathPathChunks::tryGrowLessRecent(
const SwathPathResamplingPositions& positions)
137 if (chunks.empty())
return false;
139 const auto & entries = positions.getEntries();
140 const auto leastRecentIndex = entries.frontIndex();
141 const auto mostRecentIndex = entries.backIndex();
144 while (1 <
static_cast<int32_t
>(chunks.front().extent.a - leastRecentIndex)) {
146 SwathPathChunk chunk;
147 chunk.extent.b = chunks.front().extent.a;
148 chunk.support.b = chunk.extent.b + std::min(skirtSize, mostRecentIndex - chunk.extent.b);
150 chunk.extent.a = chunk.extent.b - std::min(preferredExtent, chunk.extent.b - leastRecentIndex);
151 chunk.support.a = chunk.extent.a - std::min(skirtSize, chunk.extent.a - leastRecentIndex);
153 assert(chunk.extent.a - chunk.support.a <= chunk.support.b - chunk.support.a);
154 assert(chunk.extent.b - chunk.support.a <= chunk.support.b - chunk.support.a);
156 assert(
static_cast<int32_t
>(chunk.extent.a - leastRecentIndex) <
static_cast<int32_t
>(chunks.front().extent.a - leastRecentIndex));
158 chunks.pushFront(chunk);
164bool Cogs::Core::EchoSounder::SwathPathChunks::update(
const SwathPathResamplingPositions& positions)
166 if (positions.getEntries().count() < 2) {
167 auto count = chunks.count();
173 if (resamplingPosGen != positions.getGeneration()) {
174 resamplingPosGen = positions.getGeneration();
182 bool rv1 = retireEvictedPositions(positions);
183 bool rv2 = seedIfQueueEmpty(positions);
184 bool rv3 = tryGrowMoreRecent(positions);
185 bool rv4 = tryGrowLessRecent(positions);
187 bool rv = rv0 || rv1 || rv2 || rv3 || rv4;
189 if (rv && !chunks.empty()) {
190 for (uint32_t i = 0; i < chunks.count(); i++) {
191 chunks[chunks.frontIndex() + i].flags = SwathPathChunkFlag::None;
193 chunks[chunks.frontIndex()].flags |= SwathPathChunkFlag::Tail;
194 chunks[chunks.backIndex()].flags |= SwathPathChunkFlag::Head;
199 VERBOSE_WRAP(std::cerr <<
"--- Chunks: " << rv0 <<
"-" << rv1 <<
"-" << rv2 <<
"-" << rv3 <<
"-" << rv4 <<
"\n");
200 for (uint32_t i = 0; i < chunks.count(); i++) {
201 const auto & c = chunks[chunks.frontIndex() + i];
202 VERBOSE_WRAP(std::cerr << (chunks.frontIndex() + i) <<
": "
203 <<
"extent={" << c.extent.a <<
", " << c.extent.b <<
"}, "
204 <<
"suppport={" << c.support.a <<
", " << c.support.b <<
"}, "
205 <<
"closed={" << ((c.flags & 1) != 0) <<
", " << ((c.flags & 2) != 0) <<
"}\n");
208 assert(c.extent.a - c.support.a <= c.support.b - c.support.a);
209 assert(c.extent.b - c.support.a <= c.support.b - c.support.a);
212 assert(chunks[chunks.frontIndex() + i - 1].extent.b == c.extent.a);
214 if (i + 1 < chunks.count()) {
215 assert(c.extent.b == chunks[chunks.frontIndex() + i + 1].extent.a);
218 assert(positions.getEntries().validIndex(c.extent.a));
219 assert(positions.getEntries().validIndex(c.extent.b));
220 assert(positions.getEntries().validIndex(c.support.a));
221 assert(positions.getEntries().validIndex(c.support.b));