[ox/ptrarith] Fix NodeBuffer to properly handle removing only node
This commit is contained in:
		
							
								
								
									
										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;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user