From e3fdbb17c5d30f91109bc7535672c3c73e70439d Mon Sep 17 00:00:00 2001 From: ened Date: Fri, 8 Nov 2024 01:13:23 +0900 Subject: [PATCH] Add DataItem for binary key, value --- KissMeme/Sources/KissDB.swift | 177 +++++++++++++++++++++++++++++++-- kissdb/Sources/kissdb/kissdb.c | 27 +++++ kissdb/Sources/kissdb/kissdb.h | 4 +- 3 files changed, 198 insertions(+), 10 deletions(-) diff --git a/KissMeme/Sources/KissDB.swift b/KissMeme/Sources/KissDB.swift index 3344b80..6133330 100644 --- a/KissMeme/Sources/KissDB.swift +++ b/KissMeme/Sources/KissDB.swift @@ -28,6 +28,16 @@ public class KissDB: NSObject { } } + public struct DataItem { + public let key: Data + public let value: Data + + public init(key: Data, value: Data) { + self.key = key + self.value = value + } + } + private let cPtr: OpaquePointer private let cError: UnsafeMutablePointer! @@ -82,9 +92,9 @@ public class KissDB: NSObject { let key = CString(item.key) let value = CString(item.value) - cItem.pointee.key = UnsafeMutableRawPointer(key.mutableString) + cItem.pointee.key = UnsafeRawPointer(key.cstring) cItem.pointee.key_size = UInt64(key.size) - cItem.pointee.data = UnsafeMutableRawPointer(value.mutableString) + cItem.pointee.data = UnsafeRawPointer(value.cstring) cItem.pointee.data_size = UInt64(value.size) guard kiss_db_insert(cPtr, cItem, true, cError) else { @@ -92,11 +102,42 @@ public class KissDB: NSObject { } } + public func insert(item: DataItem) throws { + let cItem = UnsafeMutablePointer.allocate(capacity: 1) + defer { + cItem.deallocate() + } + + try item.key.withUnsafeBytes { keyRawPointer in + cItem.pointee.key = keyRawPointer.baseAddress! + cItem.pointee.key_size = UInt64(keyRawPointer.count) + + try item.value.withUnsafeBytes { dataRawPointer in + cItem.pointee.data = dataRawPointer.baseAddress! + cItem.pointee.data_size = UInt64(dataRawPointer.count) + + guard kiss_db_insert(cPtr, cItem, true, cError) else { + throw KissDBError.general(cError.code, cError.message) + } + } + } + } + public func insert(from: @escaping ((Int)->Item?), count: Int) throws { - let obj = InsertCallbackObject(insertCallback: from, maxCount: count) + let obj = InsertItemCallbackObject(insertCallback: from, maxCount: count) let userPtr = Unmanaged.passUnretained(obj).toOpaque() - guard kiss_db_insert_from(cPtr, false, InsertCallbackObject.insertCallback, userPtr, cError) else { + guard kiss_db_insert_from(cPtr, false, InsertItemCallbackObject.insertCallback, userPtr, cError) else { + throw KissDBError.general(cError.code, cError.message) + } + } + + // TODO: impl. more + public func insert_experimental(from: @escaping ((Int)->DataItem?), count: Int) throws { + let obj = InsertDataItemCallbackObject(insertCallback: from, maxCount: count) + let userPtr = Unmanaged.passUnretained(obj).toOpaque() + + guard kiss_db_insert_from(cPtr, false, InsertDataItemCallbackObject.insertCallback, userPtr, cError) else { throw KissDBError.general(cError.code, cError.message) } } @@ -109,6 +150,14 @@ public class KissDB: NSObject { } } + public func delete(key: Data) throws { + try key.withUnsafeBytes { keyRawPointer in + guard kiss_db_delete(cPtr, keyRawPointer.baseAddress!, UInt32(keyRawPointer.count), cError) else { + throw KissDBError.general(cError.code, cError.message) + } + } + } + public func delete(key: String, into: ((Item)->Bool)?) throws { let key = CString(key) @@ -119,6 +168,16 @@ public class KissDB: NSObject { } } + public func delete(key: Data, into: ((DataItem)->Bool)?) throws { + try key.withUnsafeBytes { keyRawPointer in + let obj = DataItemCallbackObject(itemCallback: into) + let userPtr = Unmanaged.passUnretained(obj).toOpaque() + guard kiss_db_delete_into(cPtr, keyRawPointer.baseAddress!, UInt32(keyRawPointer.count), DataItemCallbackObject.deleteCallback, userPtr, cError) else { + throw KissDBError.general(cError.code, cError.message) + } + } + } + public func select(key: String, into: ((Item)->Bool)?) throws { let key = CString(key) @@ -129,6 +188,17 @@ public class KissDB: NSObject { } } + public func select(key: Data, into: ((DataItem)->Bool)?) throws { + try key.withUnsafeBytes { keyRawPointer in + let obj = DataItemCallbackObject(itemCallback: into) + let userPtr = Unmanaged.passUnretained(obj).toOpaque() + guard kiss_db_select(cPtr, keyRawPointer.baseAddress!, UInt32(keyRawPointer.count), DataItemCallbackObject.selectCallback, userPtr, cError) else { + throw KissDBError.general(cError.code, cError.message) + } + } + } + + /// - Remark: /// The result of `Item` is not sorted. /// public func select(into: ((Item)->Bool)?) throws { @@ -138,10 +208,21 @@ public class KissDB: NSObject { throw KissDBError.general(cError.code, cError.message) } } + + /// - Remark: + /// The result of `Item` is not sorted. + /// + public func select(into: ((DataItem)->Bool)?) throws { + let obj = DataItemCallbackObject(itemCallback: into) + let userPtr = Unmanaged.passUnretained(obj).toOpaque() + guard kiss_db_select_all(cPtr, DataItemCallbackObject.selectCallback, userPtr, cError) else { + throw KissDBError.general(cError.code, cError.message) + } + } } -class InsertCallbackObject: NSObject { +class InsertItemCallbackObject: NSObject { let insertCallback: ((Int)->KissDB.Item?) let maxCount: Int @@ -156,7 +237,7 @@ class InsertCallbackObject: NSObject { } static let insertCallback: kiss_insert_callback = { (item: UnsafeMutablePointer?, userPtr: UnsafeMutableRawPointer?) -> kiss_bool in - let obj = Unmanaged.fromOpaque(userPtr!).takeUnretainedValue() + let obj = Unmanaged.fromOpaque(userPtr!).takeUnretainedValue() guard let item = item else { return false } @@ -168,9 +249,9 @@ class InsertCallbackObject: NSObject { obj.cKey = CString(newItem.key) obj.cValue = CString(newItem.value) - item.pointee.key = UnsafeMutableRawPointer(obj.cKey!.mutableString) + item.pointee.key = UnsafeRawPointer(obj.cKey!.cstring) item.pointee.key_size = UInt64(obj.cKey!.size) - item.pointee.data = UnsafeMutableRawPointer(obj.cValue!.mutableString) + item.pointee.data = UnsafeRawPointer(obj.cValue!.cstring) item.pointee.data_size = UInt64(obj.cValue!.size) // Continue to insert remained items @@ -179,6 +260,46 @@ class InsertCallbackObject: NSObject { } +class InsertDataItemCallbackObject: NSObject { + + let insertCallback: ((Int)->KissDB.DataItem?) + let maxCount: Int + + private var index: Int = 0 +// private var cKey: CString? +// private var cValue: CString? + + init(insertCallback: @escaping ((Int)->KissDB.DataItem?), maxCount: Int) { + self.insertCallback = insertCallback + self.maxCount = maxCount + } + + static let insertCallback: kiss_insert_callback = { (item: UnsafeMutablePointer?, userPtr: UnsafeMutableRawPointer?) -> kiss_bool in + let obj = Unmanaged.fromOpaque(userPtr!).takeUnretainedValue() + guard let item = item else { + return false + } + + guard obj.index < obj.maxCount, let newItem = obj.insertCallback(obj.index) else { + return false + } + obj.index += 1 + + // TODO: impl. more +// obj.cKey = CString(newItem.key) +// obj.cValue = CString(newItem.value) +// +// item.pointee.key = UnsafeRawPointer(obj.cKey!.cstring) +// item.pointee.key_size = UInt64(obj.cKey!.size) +// item.pointee.data = UnsafeRawPointer(obj.cValue!.cstring) +// item.pointee.data_size = UInt64(obj.cValue!.size) + + // Continue to insert remained items + return true + } +} + + class ItemCallbackObject: NSObject { let itemCallback: ((KissDB.Item)->Bool)? @@ -217,6 +338,46 @@ class ItemCallbackObject: NSObject { } +class DataItemCallbackObject: NSObject { + + let itemCallback: ((KissDB.DataItem)->Bool)? + + init(itemCallback: ((KissDB.DataItem)->Bool)?) { + self.itemCallback = itemCallback + } + + static let deleteCallback: kiss_delete_callback = { (item: UnsafeMutablePointer!, userPtr: UnsafeMutableRawPointer?) -> kiss_bool in + let obj = Unmanaged.fromOpaque(userPtr!).takeUnretainedValue() + if let itemCallback = obj.itemCallback, let item = item { + let cKey = item.pointee.key.bindMemory(to: UInt8.self, capacity: Int(item.pointee.key_size)) + let cValue = item.pointee.data.bindMemory(to: UInt8.self, capacity: Int(item.pointee.data_size)) + let key = Data(bytes: UnsafeMutableRawPointer(mutating: cKey), count: Int(item.pointee.key_size)) + let value = Data(bytes: UnsafeMutableRawPointer(mutating: cValue), count: Int(item.pointee.data_size)) + let item = KissDB.DataItem(key: key, value: value) + return itemCallback(item) + } + // Continue to delete remained items + return true + } + + static let selectCallback: kiss_select_callback = { (item: UnsafeMutablePointer!, userPtr: UnsafeMutableRawPointer?) -> kiss_bool in + let obj = Unmanaged.fromOpaque(userPtr!).takeUnretainedValue() + if let itemCallback = obj.itemCallback, let item = item { + let cKey = item.pointee.key.bindMemory(to: UInt8.self, capacity: Int(item.pointee.key_size)) + let cValue = item.pointee.data.bindMemory(to: UInt8.self, capacity: Int(item.pointee.data_size)) + //let key = Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: cKey), count: Int(item.pointee.key_size), deallocator: .none) + //let value = Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: cValue), count: Int(item.pointee.data_size), deallocator: .none) + let key = Data(bytes: UnsafeMutableRawPointer(mutating: cKey), count: Int(item.pointee.key_size)) + let value = Data(bytes: UnsafeMutableRawPointer(mutating: cValue), count: Int(item.pointee.data_size)) + let item = KissDB.DataItem(key: key, value: value) + return itemCallback(item) + } + // Continue to select remained items + return true + } +} + + extension UnsafeMutablePointer where Pointee == kiss_db_error_t { var code: Int { Int(pointee.code) diff --git a/kissdb/Sources/kissdb/kissdb.c b/kissdb/Sources/kissdb/kissdb.c index 9b31230..8fc3ea5 100644 --- a/kissdb/Sources/kissdb/kissdb.c +++ b/kissdb/Sources/kissdb/kissdb.c @@ -151,6 +151,33 @@ kiss_bool kiss_db_insert_from(kiss_db_ptr ptr, kiss_bool update, kiss_insert_cal } +typedef struct kiss_db_insert_preparation_t { + // TODO: imple. more.......... +} kiss_db_insert_preparation_t; + + +kiss_db_insert_preparation_t* kiss_db_insert_preparation_create(void) +{ + kiss_db_insert_preparation_t* ptr = (kiss_db_insert_preparation_t*) malloc(sizeof(kiss_db_insert_preparation_t)); + + return ptr; +} + + +void kiss_db_insert_preparation_release(kiss_db_insert_preparation_t* ptr) +{ + free(ptr); +} + + +kiss_bool kiss_db_insert_prepartion_do_from(kiss_db_ptr ptr, kiss_bool update, kiss_insert_callback callback, void* callback_user_ptr, kiss_db_error_t* error) +{ + // TODO: imple. more.......... + + return false; +} + + kiss_bool kiss_db_delete(kiss_db_ptr ptr, const void* in_key, kiss_uint in_key_size, kiss_db_error_t* error) { int rc = 0; diff --git a/kissdb/Sources/kissdb/kissdb.h b/kissdb/Sources/kissdb/kissdb.h index b6d597d..742dcc0 100644 --- a/kissdb/Sources/kissdb/kissdb.h +++ b/kissdb/Sources/kissdb/kissdb.h @@ -39,9 +39,9 @@ typedef struct { typedef struct { - void* key; + const void* key; kiss_uint64 key_size; - void* data; + const void* data; kiss_uint64 data_size; } kiss_db_item_t;