[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