absolutely amazingly, basically working skip list

This commit is contained in:
2023-10-21 18:49:42 +02:00
parent dd0614c49a
commit 150cffd5b3
7 changed files with 116 additions and 68 deletions

View File

@@ -10,6 +10,7 @@
#include "memman.hpp"
#include "misc.hpp"
#include "mutex.hpp"
#include "rand.h"
#include "serial.hpp"
#include "task.hpp"
#include "timer.hpp"
@@ -165,6 +166,9 @@ void kmain() {
(*ctor)();
init_timer();
srand(micros);// NOLINT
new_ktask(ktask_main, "ktask_main");
new_ktask(dummy_task, "dummy");
init_tasks();

View File

@@ -1,5 +1,5 @@
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_sources(kernel.elf PRIVATE mutex.cpp cv.cpp cppsupport.cpp Spinlock.cpp LockGuard.cpp)
target_sources(kernel.elf PRIVATE mutex.cpp cv.cpp cppsupport.cpp Spinlock.cpp LockGuard.cpp rand.c)
add_subdirectory(templates)

19
src/kernel/rand.c Normal file
View File

@@ -0,0 +1,19 @@
//
// Created by Stepan Usatiuk on 21.10.2023.
//
#include "rand.h"
// The following functions define a portable implementation of rand and srand.
static unsigned long int next = 1;// NB: "unsigned long int" is assumed to be 32 bits wide
int rand(void)// RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int) (next / 65536ULL) % 32768;
}
void srand(unsigned int seed) {
next = seed;
}

21
src/kernel/rand.h Normal file
View File

@@ -0,0 +1,21 @@
//
// Created by Stepan Usatiuk on 21.10.2023.
//
#ifndef OS2_RAND_H
#define OS2_RAND_H
#ifdef __cplusplus
extern "C" {
#endif
// The following functions define a portable implementation of rand and srand.
#define RAND_MAX 32767
int rand(void);
void srand(unsigned int seed);
#ifdef __cplusplus
}
#endif
#endif//OS2_RAND_H

View File

@@ -5,8 +5,12 @@
#ifndef OS2_STRING_H
#define OS2_STRING_H
#include <cstddef>
#include <cstdint>
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
inline void *memcpy(void *dest, const void *src, size_t n) {
uint8_t *pdest = (uint8_t *) dest;
@@ -98,4 +102,8 @@ inline void strcpy(const char *src, char *dst) {
dst[i] = '\0';
}
#ifdef __cplusplus
}
#endif
#endif//OS2_STRING_H

View File

@@ -1,24 +1,17 @@
#ifndef SKIPLIST_H
#define SKIPLIST_H
static bool seedSet = false;
class SeedSetter {
public:
SeedSetter() noexcept {
if (!seedSet) {
std::cout << "seed set!" << std::endl;
srand(time(nullptr));// NOLINT
seedSet = true;
}
}
};
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <utility>
[[maybe_unused]] static SeedSetter seedSetter;
#include "rand.h"
#include "serial.hpp"
template<typename K, typename V>
class SkipList {
static constexpr size_t maxL{31};
friend SkipListTester;
public:
struct Node {
@@ -41,13 +34,14 @@ private:
~NodeAllocator() noexcept {
for (int i = top; i >= 0; i--) {
delete nodes[i];
// delete nodes[i];
}
}
void push(Node *&e) {
if (top >= size - 1) {
delete e;
// TODO: ????
// delete e;
return;
}
nodes[++top] = e;
@@ -72,10 +66,13 @@ private:
};
static int randomL() {
return ffs(rand()) - 1;// NOLINT
int ret = __builtin_ffs(rand());
assert(ret >= 0);
return ret;// NOLINT
}
static inline NodeAllocator nodeAllocator;
// static inline NodeAllocator nodeAllocator;
NodeAllocator nodeAllocator;
Node *root;
Node *endnode;
@@ -355,7 +352,7 @@ public:
struct SkipListIterator {
using iterator_category = std::forward_iterator_tag;
// using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = const V;
using pointer = value_type *;
@@ -400,20 +397,20 @@ public:
const_iterator end() const { return SkipListIterator(endnode); }
void print() const {
std::cout << "LIST STATUS" << std::endl;
for (size_t i = 0; i <= curL; i++) {
Node *n = root->next[i];
std::cout << "L " << i << ": ";
while (n != nullptr && n->next[0]) {
std::cout << "GUARD: " << n->end << " KEY: " << n->key << " RANGE: " << n->data
<< " <<<<<";
n = n->next[i];
}
std::cout << std::endl;
}
};
// void print() const {
// std::cout << "LIST STATUS" << std::endl;
//
// for (size_t i = 0; i <= curL; i++) {
// Node *n = root->next[i];
// std::cout << "L " << i << ": ";
// while (n != nullptr && n->next[0]) {
// std::cout << "GUARD: " << n->end << " KEY: " << n->key << " RANGE: " << n->data
// << " <<<<<";
// n = n->next[i];
// }
// std::cout << std::endl;
// }
// };
};

View File

@@ -5,6 +5,7 @@
#include "TestTemplates.hpp"
#include "SkipList.hpp"
#include "String.hpp"
#include "Vector.hpp"
#include "serial.hpp"
@@ -144,41 +145,39 @@ public:
}
};
//class SkipListTester {
//public:
// bool test() {
// SkipList<int, std::string> test1;
//
// test1.add(5, "test5", false);
// test1.add(999, "test999", false);
// test1.add(5, "test5", false);
// test1.add(1, "test1", false);
// test1.add(999, "test999", false);
//
// assert(test1.find(5)->data == "test5");
// assert(test1.find(1)->data == "test1");
// assert(test1.find(999)->data == "test999");
//
// test1.erase(1);
// assert(test1.find(1)->data != "test1");
// test1.add(87, "test87", false);
// assert(test1.find(87)->data == "test87");
//
// auto p2 = test1.lower_bound_update(78);
// assert(p2->data == "test87");
// test1.add(78, "test78", true);
// assert(test1.find(78)->data == "test78");
//
// assert(IT::test());
//
// return true;
// }
//};
//
class SkipListTester {
public:
bool test() {
SkipList<int, String> test1;
test1.add(5, "test5", false);
test1.add(999, "test999", false);
test1.add(5, "test5", false);
test1.add(1, "test1", false);
test1.add(999, "test999", false);
assert(test1.find(5)->data == "test5");
assert(test1.find(1)->data == "test1");
assert(test1.find(999)->data == "test999");
test1.erase(1);
assert(test1.find(1)->data != "test1");
test1.add(87, "test87", false);
assert(test1.find(87)->data == "test87");
auto p2 = test1.lower_bound_update(78);
assert(p2->data == "test87");
test1.add(78, "test78", true);
assert(test1.find(78)->data == "test78");
return true;
}
};
int test_templates() {
// SkipListTester SLTester;
// SLTester.test();
SkipListTester SLTester;
SLTester.test();
StringTester stringTester;
stringTester.test();
VectorTester vectorTester;