Add contiguous linked list type for the new file store
This commit is contained in:
parent
193492c518
commit
21e72a0513
8
deps/ox/src/ox/fs/CMakeLists.txt
vendored
8
deps/ox/src/ox/fs/CMakeLists.txt
vendored
@ -35,6 +35,14 @@ install(
|
|||||||
include/ox/fs
|
include/ox/fs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
filestore/linkedlist.hpp
|
||||||
|
filestore/ptr.hpp
|
||||||
|
DESTINATION
|
||||||
|
include/ox/fs/filestore
|
||||||
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
filesystem/filesystem.hpp
|
filesystem/filesystem.hpp
|
||||||
|
138
deps/ox/src/ox/fs/filestore/linkedlist.hpp
vendored
Normal file
138
deps/ox/src/ox/fs/filestore/linkedlist.hpp
vendored
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ptr.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
namespace fs {
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
class LinkedList {
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Header {
|
||||||
|
ox::LittleEndian<size_t> size = sizeof(Header);
|
||||||
|
ox::LittleEndian<size_t> firstItem = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Item {
|
||||||
|
ox::LittleEndian<size_t> size = sizeof(Item);
|
||||||
|
ox::LittleEndian<size_t> prev = 0;
|
||||||
|
ox::LittleEndian<size_t> next = 0;
|
||||||
|
|
||||||
|
Item(size_t size) {
|
||||||
|
this->size = size;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ItemPtr: public ox::fs::Ptr<Item, size_t> {
|
||||||
|
inline ItemPtr(void *dataStart, void *dataEnd, size_t itemOffset, size_t size):
|
||||||
|
Ptr<Item, size_t>(dataStart, dataEnd, itemOffset, size) {}
|
||||||
|
|
||||||
|
inline ItemPtr(void *dataStart, void *dataEnd, size_t itemOffset) {
|
||||||
|
// make sure this can be read as an Item, and then use Item::size for the size
|
||||||
|
uint8_t *itemStart = static_cast<uint8_t*>(dataStart) + itemOffset;
|
||||||
|
if (static_cast<uint8_t*>(dataEnd) - itemStart >= static_cast<size_t>(sizeof(Item))) {
|
||||||
|
auto item = (Item*) (static_cast<uint8_t*>(dataStart) + itemOffset);
|
||||||
|
ItemPtr(dataStart, dataEnd, itemOffset, item->size);
|
||||||
|
} else {
|
||||||
|
ItemPtr(dataStart, dataEnd, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Header m_header;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ItemPtr firstItem();
|
||||||
|
|
||||||
|
ItemPtr prev(Item *item);
|
||||||
|
|
||||||
|
ItemPtr next(Item *item);
|
||||||
|
|
||||||
|
ItemPtr ptr(size_t offset);
|
||||||
|
|
||||||
|
ItemPtr ptr(uint8_t *item);
|
||||||
|
|
||||||
|
//private:
|
||||||
|
ItemPtr malloc(size_t size);
|
||||||
|
|
||||||
|
void compact(void (*cb)(ItemPtr itemMoved));
|
||||||
|
|
||||||
|
uint8_t *data();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::firstItem() {
|
||||||
|
return ptr(m_header.firstItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::prev(Item *item) {
|
||||||
|
return ptr(item->prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::next(Item *item) {
|
||||||
|
return ptr(item->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::ptr(size_t offset) {
|
||||||
|
return ItemPtr(this, this + 1, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::ptr(uint8_t *item) {
|
||||||
|
return ItemPtr(this, this + 1, reinterpret_cast<size_t>(static_cast<uint8_t*>(item - static_cast<uint8_t*>(this))));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::malloc(size_t size) {
|
||||||
|
auto out = ItemPtr(this, this + 1, 0, size);
|
||||||
|
if (out.valid()) {
|
||||||
|
new (out) Item(size);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
void LinkedList<size_t>::compact(void (*cb)(ItemPtr)) {
|
||||||
|
auto src = ptr(firstItem());
|
||||||
|
auto dest = data();
|
||||||
|
while (src.valid()) {
|
||||||
|
// move node
|
||||||
|
ox_memcpy(dest, src, src.size());
|
||||||
|
if (cb) {
|
||||||
|
cb(ptr(dest));
|
||||||
|
}
|
||||||
|
// update surrounding nodes
|
||||||
|
auto prev = ptr(dest->next);
|
||||||
|
if (prev) {
|
||||||
|
prev->next = dest;
|
||||||
|
}
|
||||||
|
auto next = ptr(dest->next);
|
||||||
|
if (next) {
|
||||||
|
next->prev = dest;
|
||||||
|
}
|
||||||
|
// update iterators
|
||||||
|
src = ptr(dest->next);
|
||||||
|
dest += ptr(dest)->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename size_t>
|
||||||
|
uint8_t *LinkedList<size_t>::data() {
|
||||||
|
return reinterpret_cast<uint8_t*>(this + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
116
deps/ox/src/ox/fs/filestore/ptr.hpp
vendored
Normal file
116
deps/ox/src/ox/fs/filestore/ptr.hpp
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/std.hpp>
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
namespace fs {
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
class Ptr {
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t *m_dataStart = nullptr;
|
||||||
|
uint8_t *m_dataEnd = nullptr;
|
||||||
|
size_t m_itemOffset = 0;
|
||||||
|
size_t m_itemSize = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline Ptr() = default;
|
||||||
|
|
||||||
|
inline Ptr(void *dataStart, void *dataEnd, size_t itemOffset, size_t itemSize = sizeof(T)) {
|
||||||
|
// do some sanity checks before assuming this is valid
|
||||||
|
if (itemSize >= sizeof(T) and
|
||||||
|
m_dataStart and
|
||||||
|
m_dataStart < m_dataEnd and
|
||||||
|
m_dataStart + m_itemOffset + m_itemSize < m_dataEnd) {
|
||||||
|
m_dataStart = static_cast<uint8_t*>(dataStart);
|
||||||
|
m_dataEnd = static_cast<uint8_t*>(dataEnd);
|
||||||
|
m_itemOffset = itemOffset;
|
||||||
|
m_itemSize = itemSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Ptr(void *dataStart, void *dataEnd, void *item, size_t itemSize = sizeof(T)) {
|
||||||
|
Ptr(dataStart, dataEnd, reinterpret_cast<size_t>(static_cast<uint8_t*>(item) - static_cast<uint8_t*>(dataStart)), itemSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool valid() const;
|
||||||
|
|
||||||
|
inline size_t size() const;
|
||||||
|
|
||||||
|
inline size_t offset() const;
|
||||||
|
|
||||||
|
inline T *operator->() const;
|
||||||
|
|
||||||
|
inline operator T*() const;
|
||||||
|
|
||||||
|
inline operator size_t() const;
|
||||||
|
|
||||||
|
inline T &operator*() const;
|
||||||
|
|
||||||
|
inline Ptr &operator=(size_t offset);
|
||||||
|
|
||||||
|
inline Ptr &operator+=(size_t offset);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline bool Ptr<T, size_t>::valid() const {
|
||||||
|
return m_dataStart and m_itemOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline size_t Ptr<T, size_t>::size() const {
|
||||||
|
return m_itemSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline size_t Ptr<T, size_t>::offset() const {
|
||||||
|
return m_itemOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline T *Ptr<T, size_t>::operator->() const {
|
||||||
|
return (T*) m_dataStart + m_itemOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline Ptr<T, size_t>::operator T*() const {
|
||||||
|
return (T*) m_dataStart + m_itemOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline Ptr<T, size_t>::operator size_t() const {
|
||||||
|
if (valid()) {
|
||||||
|
return m_itemOffset;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline T &Ptr<T, size_t>::operator*() const {
|
||||||
|
return *static_cast<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline Ptr<T, size_t> &Ptr<T, size_t>::operator=(size_t offset) {
|
||||||
|
m_itemOffset = offset;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename size_t>
|
||||||
|
inline Ptr<T, size_t> &Ptr<T, size_t>::operator+=(size_t offset) {
|
||||||
|
m_itemOffset += offset;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
10
deps/ox/src/ox/fs/test/tests.cpp
vendored
10
deps/ox/src/ox/fs/test/tests.cpp
vendored
@ -13,6 +13,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <ox/fs/fs.hpp>
|
#include <ox/fs/fs.hpp>
|
||||||
#include <ox/std/std.hpp>
|
#include <ox/std/std.hpp>
|
||||||
|
#include <ox/fs/filestore/linkedlist.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ox;
|
using namespace ox;
|
||||||
@ -326,6 +327,15 @@ map<string, int(*)(string)> tests = {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"LinkedList::insert",
|
||||||
|
[](string) {
|
||||||
|
ox::fs::LinkedList<uint32_t> list;
|
||||||
|
list.malloc(50);
|
||||||
|
list.firstItem();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
72
deps/ox/src/ox/std/byteswap.hpp
vendored
72
deps/ox/src/ox/std/byteswap.hpp
vendored
@ -12,6 +12,10 @@
|
|||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
|
inline int8_t byteSwap(int8_t i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
inline int16_t byteSwap(int16_t i) {
|
inline int16_t byteSwap(int16_t i) {
|
||||||
return (i << 8) | (i >> 8);
|
return (i << 8) | (i >> 8);
|
||||||
}
|
}
|
||||||
@ -34,6 +38,10 @@ inline int64_t byteSwap(int64_t i) {
|
|||||||
((i << 56) & 0xff00000000000000);
|
((i << 56) & 0xff00000000000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint16_t byteSwap(uint8_t i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
inline uint16_t byteSwap(uint16_t i) {
|
inline uint16_t byteSwap(uint16_t i) {
|
||||||
return (i << 8) | (i >> 8);
|
return (i << 8) | (i >> 8);
|
||||||
}
|
}
|
||||||
@ -99,6 +107,70 @@ class LittleEndian {
|
|||||||
return value != ox::bigEndianAdapt(m_value);
|
return value != ox::bigEndianAdapt(m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline T operator+(T value) const {
|
||||||
|
return ox::bigEndianAdapt(m_value) + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator+=(T other) {
|
||||||
|
auto newVal = *this + other;
|
||||||
|
m_value = ox::bigEndianAdapt(newVal);
|
||||||
|
return newVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator-(T value) {
|
||||||
|
return ox::bigEndianAdapt(m_value) - value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator-=(T other) {
|
||||||
|
auto newVal = *this - other;
|
||||||
|
m_value = ox::bigEndianAdapt(newVal);
|
||||||
|
return newVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator*(T value) {
|
||||||
|
return ox::bigEndianAdapt(m_value) * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator*=(T other) {
|
||||||
|
auto newVal = *this * other;
|
||||||
|
m_value = ox::bigEndianAdapt(newVal);
|
||||||
|
return newVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator/(T value) {
|
||||||
|
return ox::bigEndianAdapt(m_value) / value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T operator/=(T other) {
|
||||||
|
auto newVal = *this / other;
|
||||||
|
m_value = ox::bigEndianAdapt(newVal);
|
||||||
|
return newVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefix increment
|
||||||
|
inline T &operator++() {
|
||||||
|
return operator+=(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Postfix increment
|
||||||
|
inline T operator++(int) {
|
||||||
|
auto old = *this;
|
||||||
|
++*this;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefix decrement
|
||||||
|
inline T &operator--() {
|
||||||
|
return operator-=(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Postfix decrement
|
||||||
|
inline T operator--(int) {
|
||||||
|
auto old = *this;
|
||||||
|
--*this;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
2
deps/ox/src/ox/std/memops.hpp
vendored
2
deps/ox/src/ox/std/memops.hpp
vendored
@ -11,6 +11,6 @@
|
|||||||
|
|
||||||
int ox_memcmp(const void *ptr1, const void *ptr2, size_t size);
|
int ox_memcmp(const void *ptr1, const void *ptr2, size_t size);
|
||||||
|
|
||||||
void *ox_memcpy(void *src, const void *dest, int64_t size);
|
void *ox_memcpy(void *dest, const void *src, int64_t size);
|
||||||
|
|
||||||
void *ox_memset(void *ptr, int val, int64_t size);
|
void *ox_memset(void *ptr, int val, int64_t size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user