Make FS linked list Item a template parameter

This commit is contained in:
Gary Talent 2018-03-07 22:40:38 -06:00
parent 3e63b2f816
commit 2e29f48810
3 changed files with 59 additions and 59 deletions

View File

@ -18,11 +18,11 @@ class FileStoreTemplate: public FileStore {
private: private:
struct __attribute__((packed)) FileStoreData { struct __attribute__((packed)) FileStoreData {
ox::LittleEndian<size_t> rootNode = sizeof(LinkedList<size_t>); ox::LittleEndian<size_t> rootNode = sizeof(LinkedList<size_t, Item>);
}; };
size_t m_buffSize = 0; size_t m_buffSize = 0;
ox::fs::LinkedList<size_t> *m_linkedList = nullptr; ox::fs::LinkedList<size_t, Item> *m_linkedList = nullptr;
public: public:
FileStoreTemplate(void *buff, size_t buffSize); FileStoreTemplate(void *buff, size_t buffSize);
@ -57,7 +57,7 @@ class FileStoreTemplate: public FileStore {
template<typename size_t> template<typename size_t>
FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) { FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) {
m_buffSize = buffSize; m_buffSize = buffSize;
m_linkedList = static_cast<ox::fs::LinkedList<size_t>*>(buff); m_linkedList = static_cast<ox::fs::LinkedList<size_t, Item>*>(buff);
if (!m_linkedList->valid(buffSize)) { if (!m_linkedList->valid(buffSize)) {
m_buffSize = 0; m_buffSize = 0;
m_linkedList = nullptr; m_linkedList = nullptr;

View File

@ -12,33 +12,29 @@
namespace ox::fs { namespace ox::fs {
template<typename size_t> struct __attribute__((packed)) Item {
class __attribute__((packed)) LinkedList { public:
ox::LittleEndian<size_t> m_size = sizeof(Item);
public: public:
struct __attribute__((packed)) Item { ox::LittleEndian<size_t> prev = 0;
friend LinkedList; ox::LittleEndian<size_t> next = 0;
public: explicit Item(size_t size) {
ox::LittleEndian<size_t> m_size = sizeof(Item); this->m_size = size;
}
protected: size_t size() const {
ox::LittleEndian<size_t> prev = 0; return m_size;
ox::LittleEndian<size_t> next = 0; }
public: ox::fs::Ptr<uint8_t, size_t> data() {
explicit Item(size_t size) { return Ptr<uint8_t, size_t>(this, m_size, sizeof(*this), m_size - sizeof(*this));
this->m_size = size; }
} };
size_t size() const { template<typename size_t, typename Item>
return m_size; class __attribute__((packed)) LinkedList {
}
ox::fs::Ptr<uint8_t, size_t> data() {
return Ptr<uint8_t, size_t>(this, m_size, sizeof(*this), m_size - sizeof(*this));
}
};
private: private:
struct __attribute__((packed)) Header { struct __attribute__((packed)) Header {
@ -70,7 +66,7 @@ class __attribute__((packed)) LinkedList {
Header m_header; Header m_header;
public: public:
LinkedList() = default; LinkedList() = default;
explicit LinkedList(size_t size); explicit LinkedList(size_t size);
@ -109,18 +105,18 @@ class __attribute__((packed)) LinkedList {
}; };
template<typename size_t> template<typename size_t, typename Item>
LinkedList<size_t>::LinkedList(size_t size) { LinkedList<size_t, Item>::LinkedList(size_t size) {
m_header.size = size; m_header.size = size;
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::firstItem() { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::firstItem() {
return ptr(m_header.firstItem); return ptr(m_header.firstItem);
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::lastItem() { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::lastItem() {
auto first = ptr(m_header.firstItem); auto first = ptr(m_header.firstItem);
if (first.valid()) { if (first.valid()) {
return prev(first); return prev(first);
@ -128,28 +124,28 @@ typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::lastItem() {
return ItemPtr(); return ItemPtr();
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::prev(Item *item) { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::prev(Item *item) {
return ptr(item->prev); return ptr(item->prev);
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::next(Item *item) { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::next(Item *item) {
return ptr(item->next); return ptr(item->next);
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::ptr(size_t offset) { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::ptr(size_t offset) {
return ItemPtr(this, m_header.size, offset); return ItemPtr(this, m_header.size, offset);
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::ptr(void *item) { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::ptr(void *item) {
return ItemPtr(this, m_header.size, reinterpret_cast<size_t>(static_cast<uint8_t*>(item) - static_cast<uint8_t*>(this))); return ItemPtr(this, m_header.size, reinterpret_cast<size_t>(static_cast<uint8_t*>(item) - static_cast<uint8_t*>(this)));
} }
template<typename size_t> template<typename size_t, typename Item>
typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::malloc(size_t size) { typename LinkedList<size_t, Item>::ItemPtr LinkedList<size_t, Item>::malloc(size_t size) {
size += sizeof(Item); size += sizeof(Item);
if (m_header.size - m_header.bytesUsed >= size) { if (m_header.size - m_header.bytesUsed >= size) {
if (!m_header.firstItem) { if (!m_header.firstItem) {
@ -175,17 +171,21 @@ typename LinkedList<size_t>::ItemPtr LinkedList<size_t>::malloc(size_t size) {
return ItemPtr(); return ItemPtr();
} }
template<typename size_t> template<typename size_t, typename Item>
void LinkedList<size_t>::free(ItemPtr item) { void LinkedList<size_t, Item>::free(ItemPtr item) {
auto prev = this->prev(item); auto prev = this->prev(item);
auto next = this->next(item); auto next = this->next(item);
prev->next = next; if (prev.valid()) {
next->prev = prev; prev->next = next;
}
if (next.valid()) {
next->prev = prev;
}
m_header.bytesUsed -= item.size(); m_header.bytesUsed -= item.size();
} }
template<typename size_t> template<typename size_t, typename Item>
Error LinkedList<size_t>::setSize(size_t size) { Error LinkedList<size_t, Item>::setSize(size_t size) {
auto last = lastItem(); auto last = lastItem();
if ((last.valid() and last.end() >= size) or size < sizeof(m_header)) { if ((last.valid() and last.end() >= size) or size < sizeof(m_header)) {
return 1; return 1;
@ -195,18 +195,18 @@ Error LinkedList<size_t>::setSize(size_t size) {
} }
} }
template<typename size_t> template<typename size_t, typename Item>
bool LinkedList<size_t>::valid(size_t maxSize) { bool LinkedList<size_t, Item>::valid(size_t maxSize) {
return m_header.size <= maxSize; return m_header.size <= maxSize;
} }
template<typename size_t> template<typename size_t, typename Item>
size_t LinkedList<size_t>::available() { size_t LinkedList<size_t, Item>::available() {
return m_header.size - m_header.bytesUsed; return m_header.size - m_header.bytesUsed;
} }
template<typename size_t> template<typename size_t, typename Item>
void LinkedList<size_t>::compact(void (*cb)(ItemPtr)) { void LinkedList<size_t, Item>::compact(void (*cb)(ItemPtr)) {
auto src = firstItem(); auto src = firstItem();
auto dest = data(); auto dest = data();
while (src.valid()) { while (src.valid()) {
@ -217,11 +217,11 @@ void LinkedList<size_t>::compact(void (*cb)(ItemPtr)) {
} }
// update surrounding nodes // update surrounding nodes
auto prev = ptr(dest->next); auto prev = ptr(dest->next);
if (prev) { if (prev.valid()) {
prev->next = dest; prev->next = dest;
} }
auto next = ptr(dest->next); auto next = ptr(dest->next);
if (next) { if (next.valid()) {
next->prev = dest; next->prev = dest;
} }
// update iterators // update iterators
@ -230,8 +230,8 @@ void LinkedList<size_t>::compact(void (*cb)(ItemPtr)) {
} }
} }
template<typename size_t> template<typename size_t, typename Item>
uint8_t *LinkedList<size_t>::data() { uint8_t *LinkedList<size_t, Item>::data() {
return reinterpret_cast<uint8_t*>(this + 1); return reinterpret_cast<uint8_t*>(this + 1);
} }

View File

@ -338,7 +338,7 @@ map<string, int(*)(string)> tests = {
int err = 0; int err = 0;
constexpr auto buffLen = 5000; constexpr auto buffLen = 5000;
uint8_t buff[buffLen]; uint8_t buff[buffLen];
auto list = new (buff) ox::fs::LinkedList<uint32_t>(buffLen); auto list = new (buff) ox::fs::LinkedList<uint32_t, ox::fs::Item>(buffLen);
err |= !(list->malloc(50).valid()); err |= !(list->malloc(50).valid());
err |= !(list->firstItem().valid()); err |= !(list->firstItem().valid());
err |= !(list->firstItem()->size() == 50); err |= !(list->firstItem()->size() == 50);
@ -350,7 +350,7 @@ map<string, int(*)(string)> tests = {
[](string) { [](string) {
constexpr auto buffLen = 5000; constexpr auto buffLen = 5000;
uint8_t buff[buffLen]; uint8_t buff[buffLen];
auto list = new (buff) ox::fs::LinkedList<uint32_t>(buffLen); auto list = new (buff) ox::fs::LinkedList<uint32_t, ox::fs::Item>(buffLen);
ox::fs::FileStore32 fileStore(list, buffLen); ox::fs::FileStore32 fileStore(list, buffLen);
ox_assert(fileStore.format() == 0, "Filestore::format failed."); ox_assert(fileStore.format() == 0, "Filestore::format failed.");
return 0; return 0;