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()