Add contiguous linked list type for the new file store

This commit is contained in:
2018-02-18 01:03:14 -06:00
parent 193492c518
commit 21e72a0513
6 changed files with 345 additions and 1 deletions

View File

@@ -35,6 +35,14 @@ install(
include/ox/fs
)
install(
FILES
filestore/linkedlist.hpp
filestore/ptr.hpp
DESTINATION
include/ox/fs/filestore
)
install(
FILES
filesystem/filesystem.hpp

View 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
View 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;
}
}
}

View File

@@ -13,6 +13,7 @@
#include <string>
#include <ox/fs/fs.hpp>
#include <ox/std/std.hpp>
#include <ox/fs/filestore/linkedlist.hpp>
using namespace std;
using namespace ox;
@@ -326,6 +327,15 @@ map<string, int(*)(string)> tests = {
return retval;
}
},
{
"LinkedList::insert",
[](string) {
ox::fs::LinkedList<uint32_t> list;
list.malloc(50);
list.firstItem();
return 0;
}
},
},
};