Greatly simplify circular buffer logic, fixing several bugs

This commit is contained in:
Billy Laws 2023-03-15 17:52:50 +00:00
parent 01febe75c4
commit d5a15faab7

View File

@ -28,7 +28,8 @@ namespace skyline {
* @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer * @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer
* @return The amount of data written into the input buffer in units of Type * @return The amount of data written into the input buffer in units of Type
*/ */
size_t Read(span <Type> buffer, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) { template<typename CopyFunc>
size_t Read(span <Type> buffer, CopyFunc copyFunction) {
std::scoped_lock guard{mtx}; std::scoped_lock guard{mtx};
if (empty) if (empty)
@ -48,40 +49,19 @@ namespace skyline {
size = sizeBegin + sizeEnd; size = sizeBegin + sizeEnd;
} }
if (copyFunction && (copyOffset != 0 && copyOffset < sizeEnd)) { {
auto sourceEnd{start + ((copyOffset != -1) ? copyOffset : sizeEnd)}; auto sourceEnd{start + sizeEnd};
for (auto source{start}, destination{pointer}; source < sourceEnd; source++, destination++) for (; start < sourceEnd; start++, pointer++)
copyFunction(source, destination); copyFunction(start, pointer);
if (copyOffset != -1) {
std::memcpy(pointer + copyOffset, start + copyOffset, static_cast<size_t>(sizeEnd - copyOffset) * sizeof(Type));
copyOffset -= sizeEnd;
} }
} else {
if (copyOffset)
copyOffset -= static_cast<size_t>(sizeEnd) * sizeof(Type);
std::memcpy(pointer, start, static_cast<size_t>(sizeEnd) * sizeof(Type));
}
pointer += sizeEnd;
if (sizeBegin) { if (sizeBegin) {
if (copyFunction && copyOffset) { start = array.begin();
auto sourceEnd{array.begin() + ((copyOffset != -1) ? copyOffset : sizeBegin)}; auto sourceEnd{array.begin() + sizeBegin};
for (auto source{array.begin()}, destination{pointer}; source < sourceEnd; source++, destination++) for (; start < sourceEnd; start++, pointer++)
copyFunction(source, destination); copyFunction(start, pointer);
if (copyOffset != -1)
std::memcpy(array.begin() + copyOffset, pointer + copyOffset, static_cast<size_t>(sizeBegin - copyOffset) * sizeof(Type));
} else {
std::memcpy(pointer, array.begin(), static_cast<size_t>(sizeBegin) * sizeof(Type));
}
start = array.begin() + sizeBegin;
} else {
start += sizeEnd;
} }
if (start == end) if (start == end)
@ -97,48 +77,24 @@ namespace skyline {
std::scoped_lock guard{mtx}; std::scoped_lock guard{mtx};
Type *pointer{buffer.data()}; Type *pointer{buffer.data()};
ssize_t size{static_cast<ssize_t>(buffer.size())}; ssize_t remainingSize{static_cast<ssize_t>(buffer.size())};
while (size) { while (remainingSize) {
if (start <= end && end != array.end()) { ssize_t writeSize{std::min([&]() {
auto sizeEnd{std::min(array.end() - end, size)}; if (start <= end)
std::memcpy(end, pointer, static_cast<size_t>(sizeEnd) * sizeof(Type)); return array.end() - end;
pointer += sizeEnd;
size -= sizeEnd;
end += sizeEnd;
} else {
auto sizePreStart{(end == array.end()) ? std::min(start - array.begin(), size) : std::min(start - end, size)};
auto sizePostStart{std::min(array.end() - start, size - sizePreStart)};
if (sizePreStart)
std::memcpy((end == array.end()) ? array.begin() : end, pointer, static_cast<size_t>(sizePreStart) * sizeof(Type));
if (end == array.end())
end = array.begin() + sizePreStart;
else else
end += sizePreStart; return start - end - 1;
}(), remainingSize)};
pointer += sizePreStart; if (writeSize) {
size -= sizePreStart; std::memcpy(end, pointer, static_cast<size_t>(writeSize) * sizeof(Type));
remainingSize -= writeSize;
if (sizePostStart) end += writeSize;
std::memcpy(end, pointer, static_cast<size_t>(sizePostStart) * sizeof(Type)); pointer += writeSize;
if (start == array.end())
start = array.begin() + sizePostStart;
else
start += sizePostStart;
if (end == array.end())
end = array.begin() + sizePostStart;
else
end += sizePostStart;
pointer += sizePostStart;
size -= sizePostStart;
} }
if (end == array.end())
end = array.begin();
empty = false; empty = false;
} }
} }