mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
absolutely amazingly, basically working skip list
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
19
src/kernel/rand.c
Normal 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
21
src/kernel/rand.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
// }
|
||||
// };
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user