Mercurial > games > semicongine
changeset 1097:bc3efccc2bf4
tmp: move stuff to notebook
author | sam <sam@basx.dev> |
---|---|
date | Sun, 07 Apr 2024 20:12:52 +0700 |
parents | 9809bd9e2cdb |
children | 45cf94a6535c |
files | semicongine/storage.nim tests/test_storage.nim |
diffstat | 2 files changed, 49 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/semicongine/storage.nim Sun Apr 07 01:17:40 2024 +0700 +++ b/semicongine/storage.nim Sun Apr 07 20:12:52 2024 +0700 @@ -1,4 +1,5 @@ import std/marshal +import std/tables import std/strformat import std/paths import std/os @@ -8,21 +9,16 @@ import ./core const STORAGE_NAME = Path("storage.db") +const KEY_VALUE_TABLE_NAME = "shelf" type StorageType* = enum SystemStorage UserStorage # ? level storage type ? - StorageOperation = enum - Read - Write - KillWorker - Storage*[T] = object - storageType: StorageType - keyChannel: ptr Channel[(StorageOperation, string)] # false is read, true is write - dataChannel: ptr Channel[T] - thread: Thread[tuple[storageType: StorageType, keyChannel: ptr Channel[(StorageOperation, string)], dataChannel: ptr Channel[T]]] + +var db: Table[StorageType, DbConn] + proc path(storageType: StorageType): Path = case storageType: @@ -32,10 +28,11 @@ string(Path(getDataDir()) / Path(AppName())).createDir() Path(getDataDir()) / Path(AppName()) / STORAGE_NAME -proc openDb(storageType: StorageType): DbConn = - const KEY_VALUE_TABLE_NAME = "shelf" - result = open(string(storageType.path), "", "", "") - result.exec(sql(&"""CREATE TABLE IF NOT EXISTS {KEY_VALUE_TABLE_NAME} ( +proc setup(storageType: StorageType) = + if storageType in db: + return + db[storageType] = open(string(storageType.path), "", "", "") + db[storageType].exec(sql(&"""CREATE TABLE IF NOT EXISTS {KEY_VALUE_TABLE_NAME} ( key TEXT NOT NULL UNIQUE, value TEXT NOT NULL )""")) @@ -53,17 +50,17 @@ return default return to[T](dbResult) +proc purge*(storageType: StorageType) = + storageType.path().string.removeFile() + # mini async API # # LOADING ######################################3333 # # -proc purge*(storageType: StorageType) = - storageType.path().string.removeFile() - type LoadFuture*[T] = object - thread: Thread[(StorageType, string, ptr Channel[T])] + thread: Thread[(DbConn, string, ptr Channel[T])] channel: ptr Channel[T] result: T @@ -92,22 +89,22 @@ assert p.channel == nil, "Result is not available yet" return p.result -proc loadWorker[T](params: (StorageType, string, ptr Channel[T])) = - var db = params[0].openDb() - defer: db.close() - let ret = loadFromDb[T](db, params[1]) +proc loadWorker[T](params: (DbConn, string, ptr Channel[T])) {.thread.} = + let ret = loadFromDb[T](params[0], params[1]) params[2][].send(ret) proc load*[T](storageType: StorageType, key: string): LoadFuture[T] = + storageType.setup() result.channel = cast[ptr Channel[T]](allocShared0(sizeof(Channel[T]))) result.channel[].open() - createThread(result.thread, loadWorker[T], (storageType, key, result.channel)) + createThread(result.thread, loadWorker[T], (db[storageType], key, result.channel)) # STORING ######################################3333 # type StoreFuture*[T] = object - thread: Thread[(StorageType, string, ptr Channel[T], ptr Channel[bool])] + # thread: Thread[(DbConn, string, ptr Channel[T], ptr Channel[bool])] + thread: Thread[void] channel: ptr Channel[T] doneChannel: ptr Channel[bool] @@ -131,16 +128,24 @@ if ret.dataAvailable: p.cleanup() -proc storeWorker[T](params: (StorageType, string, ptr Channel[T], ptr Channel[bool])) = - var db = params[0].openDb() - defer: db.close() - storeInDb(db, params[1], params[2][].recv()) - params[3][].send(true) +# proc storeWorker[T](params: (DbConn, string, ptr Channel[T], ptr Channel[bool])) {.thread.} = + # storeInDb(params[0], params[1], params[2][].recv()) + # params[3][].send(true) + -proc store*[T](storageType: StorageType, key: string, value: T): StoreFuture[T] = - result.channel = cast[ptr Channel[T]](allocShared0(sizeof(Channel[T]))) - result.channel[].open() - result.doneChannel = cast[ptr Channel[bool]](allocShared0(sizeof(Channel[bool]))) - result.doneChannel[].open() - createThread(result.thread, storeWorker[T], (storageType, key, result.channel, result.doneChannel)) - result.channel[].send(value) +# proc store*[T](storageType: StorageType, key: string, value: T): StoreFuture[T] = + # storageType.setup() + # result.channel = cast[ptr Channel[T]](allocShared0(sizeof(Channel[T]))) + # result.channel[].open() + # result.doneChannel = cast[ptr Channel[bool]](allocShared0(sizeof(Channel[bool]))) + # result.doneChannel[].open() + # createThread(result.thread, storeWorker[T], (db[storageType], key, result.channel, result.doneChannel)) + # createThread(result.thread, storeWorker) + # result.channel[].send(value) + +proc storeWorker() {.thread.} = + echo "storeWorker" + +proc store*() = + var thread: Thread[void] + createThread(thread, storeWorker)
--- a/tests/test_storage.nim Sun Apr 07 01:17:40 2024 +0700 +++ b/tests/test_storage.nim Sun Apr 07 20:12:52 2024 +0700 @@ -3,6 +3,7 @@ import semicongine +#[ proc testSimple(storage: StorageType) = const TEST_VALUE = 42 const KEY = "test" @@ -43,6 +44,7 @@ p.awaitStored() var p1 = load[int](storage, key) assert p1.awaitResult() == i +]# proc concurrentStressTest(storage: StorageType) = var storeFutures: seq[StoreFuture[int]] @@ -50,7 +52,8 @@ for i in 1 .. 10000: let key = &"key-{i}" echo key - storeFutures.add store(storage, key, i) + store() + # storeFutures.add store(storage, key, i) for i in 1 .. 10000: echo i @@ -59,6 +62,7 @@ var p1 = load[int](storage, key) assert p1.awaitResult() == i +#[ proc main() = SystemStorage.purge() echo "SystemStorage: Testing simple store/load" @@ -81,6 +85,9 @@ # TODO: fails currently, but is likely not too important # echo "Stress test with 10'000 saves/loads and a little concurrency" # SystemStorage.concurrentStressTest() +]# when isMainModule: - main() + echo "Stress test with 10'000 saves/loads and a little concurrency" + SystemStorage.concurrentStressTest() + # main()