[ox/ptrarith] Fix NodeBuffer to properly handle removing only node
This commit is contained in:
parent
6571129686
commit
3adf0df9c7
2
deps/ox/src/ox/ptrarith/CMakeLists.txt
vendored
2
deps/ox/src/ox/ptrarith/CMakeLists.txt
vendored
@ -5,3 +5,5 @@ install(
|
||||
DESTINATION
|
||||
include/ox/ptrarith
|
||||
)
|
||||
|
||||
add_subdirectory(test)
|
||||
|
43
deps/ox/src/ox/ptrarith/nodebuffer.hpp
vendored
43
deps/ox/src/ox/ptrarith/nodebuffer.hpp
vendored
@ -19,7 +19,7 @@ class __attribute__((packed)) NodeBuffer {
|
||||
|
||||
public:
|
||||
struct __attribute__((packed)) Header {
|
||||
ox::LittleEndian<size_t> size = sizeof(Header);
|
||||
ox::LittleEndian<size_t> size = sizeof(Header); // capacity
|
||||
ox::LittleEndian<size_t> bytesUsed = sizeof(Header);
|
||||
ox::LittleEndian<size_t> firstItem = 0;
|
||||
};
|
||||
@ -67,7 +67,7 @@ class __attribute__((packed)) NodeBuffer {
|
||||
return m_current;
|
||||
}
|
||||
|
||||
bool valid() const noexcept {
|
||||
[[nodiscard]] bool valid() const noexcept {
|
||||
return m_current.valid();
|
||||
}
|
||||
|
||||
@ -113,22 +113,29 @@ class __attribute__((packed)) NodeBuffer {
|
||||
template<typename T>
|
||||
Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr);
|
||||
|
||||
ItemPtr prev(Item *item);
|
||||
[[nodiscard]] ItemPtr prev(Item *item);
|
||||
|
||||
ItemPtr next(Item *item);
|
||||
[[nodiscard]] ItemPtr next(Item *item);
|
||||
|
||||
ItemPtr ptr(size_t offset);
|
||||
[[nodiscard]] ItemPtr ptr(size_t offset);
|
||||
|
||||
ItemPtr ptr(void *item);
|
||||
[[nodiscard]] ItemPtr ptr(void *item);
|
||||
|
||||
ItemPtr malloc(size_t size);
|
||||
[[nodiscard]] ItemPtr malloc(size_t size);
|
||||
|
||||
Error free(ItemPtr item);
|
||||
[[nodiscard]] ox::Error free(ItemPtr item);
|
||||
|
||||
bool valid(size_t maxSize);
|
||||
[[nodiscard]] bool valid(size_t maxSize);
|
||||
|
||||
Error setSize(size_t size);
|
||||
/**
|
||||
* Set size, capacity.
|
||||
*/
|
||||
[[nodiscard]] ox::Error setSize(size_t size);
|
||||
|
||||
/**
|
||||
* Get size, capacity.
|
||||
* @return capacity
|
||||
*/
|
||||
size_t size();
|
||||
|
||||
/**
|
||||
@ -278,16 +285,26 @@ Error NodeBuffer<size_t, Item>::free(ItemPtr item) {
|
||||
auto prev = this->prev(item);
|
||||
auto next = this->next(item);
|
||||
if (prev.valid() && next.valid()) {
|
||||
prev->next = next.offset();
|
||||
next->prev = prev.offset();
|
||||
if (next != item) {
|
||||
prev->next = next.offset();
|
||||
next->prev = prev.offset();
|
||||
if (item.offset() == m_header.firstItem) {
|
||||
m_header.firstItem = next;
|
||||
}
|
||||
} else {
|
||||
// only one item, null out first
|
||||
oxTrace("ox::ptrarith::NodeBuffer::free") << "Nulling out firstItem.";
|
||||
m_header.firstItem = 0;
|
||||
}
|
||||
} else {
|
||||
if (!prev.valid()) {
|
||||
oxTrace("ox::ptrarith::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer:" << prev.offset();
|
||||
return OxError(1);
|
||||
}
|
||||
if (!next.valid()) {
|
||||
oxTrace("ox::ptrarith::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer:" << next.offset();
|
||||
return OxError(1);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
m_header.bytesUsed -= item.size();
|
||||
return OxError(0);
|
||||
|
2
deps/ox/src/ox/ptrarith/ptr.hpp
vendored
2
deps/ox/src/ox/ptrarith/ptr.hpp
vendored
@ -31,7 +31,7 @@ class Ptr {
|
||||
|
||||
inline Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize = sizeof(T), size_t itemTypeSize = sizeof(T));
|
||||
|
||||
inline bool valid() const;
|
||||
[[nodiscard]] inline bool valid() const;
|
||||
|
||||
inline size_t size() const;
|
||||
|
||||
|
11
deps/ox/src/ox/ptrarith/test/CMakeLists.txt
vendored
Normal file
11
deps/ox/src/ox/ptrarith/test/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
add_executable(
|
||||
PtrArithTests
|
||||
tests.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
PtrArithTests
|
||||
OxStd
|
||||
)
|
||||
|
||||
add_test("Test\\ PtrArith::setSize" PtrArithTests PtrArith::setSize)
|
69
deps/ox/src/ox/ptrarith/test/tests.cpp
vendored
Normal file
69
deps/ox/src/ox/ptrarith/test/tests.cpp
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2015 - 2018 gtalent2@gmail.com
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// make sure asserts are enabled for the test file
|
||||
#undef NDEBUG
|
||||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ox/ptrarith/nodebuffer.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/std/std.hpp>
|
||||
#include <ox/fs/filestore/filestoretemplate.hpp>
|
||||
#include <ox/fs/filesystem/filesystem.hpp>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace ox;
|
||||
|
||||
template<typename T>
|
||||
struct __attribute__((packed)) NodeType: public ox::ptrarith::Item<T> {
|
||||
public:
|
||||
int i = 0;
|
||||
size_t fullSize() const {
|
||||
return this->size() + sizeof(*this);
|
||||
}
|
||||
};
|
||||
|
||||
map<string, int(*)(string)> tests = {
|
||||
{
|
||||
{
|
||||
"PtrArith::setSize",
|
||||
[](string) {
|
||||
using BuffPtr_t = uint32_t;
|
||||
std::vector<char> buff(5 * ox::units::MB);
|
||||
auto buffer = new (buff.data()) ox::ptrarith::NodeBuffer<BuffPtr_t, NodeType<BuffPtr_t>>(buff.size());
|
||||
auto a1 = buffer->malloc(50);
|
||||
auto a2 = buffer->malloc(50);
|
||||
oxAssert(buffer->free(a1), "Free failed.");
|
||||
oxAssert(buffer->free(a2), "Free failed.");
|
||||
oxAssert(buffer->setSize(buffer->size() - buffer->available()), "Resize failed.");
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int retval = -1;
|
||||
if (argc > 1) {
|
||||
auto testName = args[1];
|
||||
string testArg = "";
|
||||
if (args[2]) {
|
||||
testArg = args[2];
|
||||
}
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
retval = tests[testName](testArg);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user