WIP, json support.

Added more dependencies for JPMS
master
Robinson 2023-08-06 00:42:52 -06:00
parent 9e5aa7c7a3
commit f5f776f7cb
No known key found for this signature in database
GPG Key ID: 8E7DB78588BD6F5C
6 changed files with 454 additions and 324 deletions

273
LICENSE
View File

@ -47,22 +47,7 @@
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- ByteUtilties - Byte manipulation and Unsigned Number Utilities
- ByteUtils - Byte manipulation and SHA/xxHash utilities
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/ByteUtilities
Copyright 2023
@ -119,7 +104,7 @@
- Objenesis -
[The Apache Software License, Version 2.0]
http://objenesis.org
https://github.com/easymock/objenesis
Objenesis Team and all contributors
- MinLog-SLF4J -
@ -127,6 +112,196 @@
https://github.com/EsotericSoftware/minlog
Nathan Sweet
- LZ4 and xxHash - LZ4 compression for Java, based on Yann Collet's work
[The Apache Software License, Version 2.0]
https://github.com/lz4/lz4
Copyright 2023
Yann Collet
Adrien Grand
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Json - Lightweight Kotlin/JSON serialization
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Json
Copyright 2023
Dorkbox LLC
Extra license information
- LibGDX Json Utils - Java object graphs, to and from JSON automatically
[The Apache Software License, Version 2.0]
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
Copyright 2011
Mario Zechner
Nathan Sweet
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Collections - Collection types and utilities to enhance the default collections.
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Collections
Copyright 2023
Dorkbox LLC
Extra license information
- Bias, BinarySearch -
[MIT License]
https://git.dorkbox.com/dorkbox/Collections
https://github.com/timboudreau/util
Copyright 2013
Tim Boudreau
- ConcurrentEntry -
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Collections
Copyright 2016
bennidi
dorkbox
- Collection Utilities (Array, ArrayMap, BooleanArray, ByteArray, CharArray, FloatArray, IdentityMap, IntArray, IntFloatMap, IntIntMap, IntMap, IntSet, LongArray, LongMap, ObjectFloatMap, ObjectIntMap, ObjectMap, ObjectSet, OrderedMap, OrderedSet) -
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Collections
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
Copyright 2011
LibGDX
Mario Zechner (badlogicgames@gmail.com)
Nathan Sweet (nathan.sweet@gmail.com)
- Predicate -
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Collections
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
Copyright 2011
LibGDX
Mario Zechner (badlogicgames@gmail.com)
Nathan Sweet (nathan.sweet@gmail.com)
xoppa
- Select, QuickSelect -
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Collections
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/utils
Copyright 2011
LibGDX
Mario Zechner (badlogicgames@gmail.com)
Nathan Sweet (nathan.sweet@gmail.com)
Jon Renner
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- MinLog - Drop-in replacement for MinLog to log through SLF4j.
[BSD 3-Clause License]
https://git.dorkbox.com/dorkbox/MinLog-SLF4J
https://github.com/EsotericSoftware/minlog
Copyright 2023
Dorkbox LLC
Nathan Sweet
Dan Brown
Extra license information
- SLF4J - Simple facade or abstraction for various logging frameworks
[MIT License]
https://www.slf4j.org
Copyright 2023
QOS.ch
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- ObjectPool - Fast, lightweight, and compatible blocking/non-blocking/soft-reference object pool for Java 8+
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/ObjectPool
Copyright 2023
Dorkbox LLC
Extra license information
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
[The Apache Software License, Version 2.0]
https://github.com/Kotlin/kotlinx.coroutines
Copyright 2023
JetBrains s.r.o.
- Conversant Disruptor - Disruptor is the highest performing intra-thread transfer mechanism available in Java.
[The Apache Software License, Version 2.0]
https://github.com/conversant/disruptor
Copyright 2023
Conversant, Inc
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
@ -207,25 +382,13 @@
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- ObjectPool - Fast, lightweight, and compatible blocking/non-blocking/soft-reference object pool for Java 8+
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/ObjectPool
Copyright 2023
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- kotlinx.coroutines - Library support for Kotlin coroutines with multiplatform support
[The Apache Software License, Version 2.0]
https://github.com/Kotlin/kotlinx.coroutines
Copyright 2023
JetBrains s.r.o.
- Conversant Disruptor - Disruptor is the highest performing intra-thread transfer mechanism available in Java.
[The Apache Software License, Version 2.0]
https://github.com/conversant/disruptor
Copyright 2023
Conversant, Inc
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
@ -233,49 +396,3 @@
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
- MinLog - Drop-in replacement for MinLog to log through SLF4j.
[BSD 3-Clause License]
https://git.dorkbox.com/dorkbox/MinLog-SLF4J
https://github.com/EsotericSoftware/minlog
Copyright 2023
Dorkbox LLC
Nathan Sweet
Dan Brown
Extra license information
- SLF4J - Simple facade or abstraction for various logging frameworks
[MIT License]
https://www.slf4j.org
Copyright 2023
QOS.ch
- Updates - Software Update Management
[The Apache Software License, Version 2.0]
https://git.dorkbox.com/dorkbox/Updates
Copyright 2021
Dorkbox LLC
Extra license information
- Kotlin -
[The Apache Software License, Version 2.0]
https://github.com/JetBrains/kotlin
Copyright 2020
JetBrains s.r.o. and Kotlin Programming Language contributors
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md

View File

@ -93,12 +93,12 @@ dependencies {
api("org.slf4j:slf4j-api:2.0.7")
api("com.dorkbox:Updates:1.1")
api("com.dorkbox:ByteUtilities:1.8")
api("com.dorkbox:Serializers:2.8")
api("com.dorkbox:ObjectPool:4.3")
api("com.dorkbox:ByteUtilities:1.13")
api("com.dorkbox:Json:1.1")
api("com.dorkbox:MinLog:2.5")
api("com.dorkbox:ObjectPool:4.3")
api("com.dorkbox:Serializers:2.9")
api("com.dorkbox:Updates:1.1")
api("com.esotericsoftware:kryo:5.5.0") {
exclude("com.esotericsoftware", "minlog") // we use our own minlog, that logs to SLF4j instead
@ -114,7 +114,6 @@ dependencies {
testImplementation("junit:junit:4.13.2")
testImplementation("ch.qos.logback:logback-classic:1.4.5")
testImplementation("org.agrona:agrona:1.14.0")
}
publishToSonatype {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021 dorkbox, llc
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -128,7 +128,9 @@ abstract class Storage(val logger: KLogger) : AutoCloseable {
abstract override fun close()
interface Builder {
/** true if the backing storage type uses strings for everything, or false if it uses something else */
/**
* true if the backing storage type uses strings for everything, or false if it uses something else
*/
val isStringBased: Boolean
/**
@ -178,6 +180,7 @@ abstract class Storage(val logger: KLogger) : AutoCloseable {
var serializer: SerializerBytes = defaultSerializer
var shared = false
@Volatile
var sharedBuild: Storage? = null
@ -278,9 +281,9 @@ abstract class Storage(val logger: KLogger) : AutoCloseable {
}
override fun hashCode(): Int {
var result = onLoad?.hashCode() ?: 0 //lambda
result = 31 * result + (onSave?.hashCode() ?: 0) //lambda
result = 31 * result + serializer.hashCode() //lambda
var result = onLoad.hashCode()
result = 31 * result + onSave.hashCode()
result = 31 * result + serializer.hashCode()
result = 31 * result + shared.hashCode()
result = 31 * result + (sharedBuild?.hashCode() ?: 0)
result = 31 * result + logger.hashCode()
@ -445,12 +448,32 @@ abstract class Storage(val logger: KLogger) : AutoCloseable {
// * JSON file storage system
// */
// class Json : Storage.FileBuilder<Json>() {
// companion object {
// // property files MUST load via strings.
// val defaultOnLoad: AccessFunc = { serializer, key, value, load ->
// val keyBytes = (key as String).decodeBase58()
// val valueBytes = (value as String).decodeBase58()
//
// val xKey = serializer.deserialize<Any>(keyBytes)!!
// val xValue = serializer.deserialize<Any>(valueBytes)
// load(xKey, xValue)
// }
//
// val defaultOnSave: AccessFunc = { serializer, key, value, save ->
// val xKey = serializer.serialize(key).encodeToBase58String()
// val xValue = serializer.serialize(value).encodeToBase58String()
// save(xKey, xValue)
// }
// }
//
// private var autoLoad = false
//
// override var onLoad: AccessFunc = defaultOnLoad
// override var onSave: AccessFunc = defaultOnSave
//
// override fun build(): Storage {
// return manageShared {
// JsonStore(file.absoluteFile, autoLoad, readOnly, readOnlyViolent, logger,
// onLoad, onSave)
// JsonStore(file.absoluteFile, autoLoad, readOnly, readOnlyViolent, logger, onLoad, onSave)
// }
// }
//

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021 dorkbox, llc
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,230 +15,208 @@
*/
package dorkbox.storage.types
///**
// * JSON property file storage system
// */
//class JsonStore(
// val dbFile: File,
// val autoLoad: Boolean,
// val readOnly: Boolean,
// val readOnlyViolent: Boolean,
// logger: KLogger,
// val onLoad: ((key: Any, value: Any, load: (key: Any, value: Any) -> Unit) -> Unit)?,
// val onSave: ((key: Any, value: Any, save: (key: Any, value: Any) -> Unit) -> Unit)?,
//) : Storage(logger) {
//
// companion object {
// private val comparator = Comparator<Any> { o1, o2 -> o1.toString().compareTo(o2.toString()) }
// }
//
// private val thread = Thread { close() }
//
// @Volatile
// private var lastModifiedTime = 0L
//
// private var output = ByteBufferOutput(64, 65535) // A reasonable max size of an object. We don't want to support it being TOO big
// private var input = Input()
//
// private val loadedProps = ConcurrentHashMap<Any, Any>()
//
// init {
// load()
//
// // Make sure that the timer is run on shutdown. A HARD shutdown will just POW! kill it, a "nice" shutdown will run the hook
// Runtime.getRuntime().addShutdownHook(thread)
//
// init("Property file storage initialized at: '$dbFile'")
// }
//
// private fun load() {
// // if we cannot load, then we create a properties file.
// if (!dbFile.canRead() && !dbFile.parentFile.mkdirs() && !dbFile.createNewFile()) {
// throw IOException("Cannot create file")
// }
//
// try {
// synchronized(dbFile) {
// FileInputStream(dbFile).use { fileStream ->
// val properties = Properties()
// properties.load(fileStream)
// lastModifiedTime = dbFile.lastModified()
//
// properties.entries.forEach { (k, v) ->
// val key = k
// val value = Base64.getDecoder().decode(v as String)
//
// input.reset()
// input.buffer = value
//
// try {
// val valueObject = serializationManager.readFullClassAndObject(input)
// if (valueObject != null) {
// loadedProps[key] = valueObject
// } else {
// logger.error("Unable to parse property (file: $dbFile) $key : $value")
// }
// } catch (e: Exception) {
// logger.error("Unable to parse property (file: $dbFile) $key : $value", e)
// }
// }
// properties.clear()
// }
// }
// } catch (e: IOException) {
// logger.error("Cannot load properties!", e)
// }
// }
//
// private fun save() {
// if (readOnly) {
// // don't accidentally save this!
// return
// }
//
// // if we cannot save, then we create a NEW properties file. It could have been DELETED out from under us (while in use!)
// if (!dbFile.canRead() && !dbFile.parentFile.mkdirs() && !dbFile.createNewFile()) {
// throw IOException("Cannot create file")
// }
//
// try {
// synchronized(dbFile) {
// val properties = object : Properties() {
// override fun keys(): Enumeration<Any> {
// val keysEnum = super.keys()
//
// val vector = Vector<Any>(size())
// while (keysEnum.hasMoreElements()) {
// vector.add(keysEnum.nextElement())
// }
//
// vector.sortWith(comparator)
// return vector.elements()
// }
// }
//
// loadedProps.forEach { (key, value) ->
// // have to serialize the value
// output.reset()
// try {
// serializationManager.writeFullClassAndObject(output, value)
// output.byteBuffer.flip()
// val valueEncoded = Base64.getEncoder().encode(output.byteBuffer)
// properties[key] = String(valueEncoded.array(), 0, valueEncoded.limit())
// } catch (e: Exception) {
// logger.error("Unable to save property: $key $value")
// }
// }
//
// FileOutputStream(dbFile, false).use { fos ->
// properties.store(fos, "Storage data, Version: $version")
// fos.flush()
// properties.clear()
// lastModifiedTime = dbFile.lastModified()
// }
// }
// } catch (e: IOException) {
// logger.error("Properties cannot save to: $dbFile", e)
// }
// }
//
// override fun file(): File {
// return dbFile
// }
//
// override fun size(): Int {
// return loadedProps.size
// }
//
// override fun contains(key: Any): Boolean {
// require(key is String) {
// "Keys for a json file must be a String"
// }
//
// if (autoLoad) {
// // we want to check the last modified time when getting, because if we edit the on-disk file, we want to load those changes
// val lastModifiedTime = dbFile.lastModified()
// if (this.lastModifiedTime != lastModifiedTime) {
// // we want to reload the info
// load()
// }
// }
//
// return loadedProps[key] != null
// }
//
// override operator fun <V> get(key: Any): V? {
// require(key is String) {
// "Keys for a json file must be a String"
// }
//
// if (autoLoad) {
// // we want to check the last modified time when getting, because if we edit the on-disk file, we want to load those changes
// val lastModifiedTime = dbFile.lastModified()
// if (this.lastModifiedTime != lastModifiedTime) {
// // we want to reload the info
// load()
// }
// }
//
// val any = loadedProps[key]
// if (any != null) {
// @Suppress("UNCHECKED_CAST")
// return any as V
// }
//
// return null
// }
//
// override operator fun set(key: Any, data: Any?) {
// require(key is String) {
// "Keys for a json file must be a String"
// }
//
// if (readOnly) {
// if (readOnlyViolent) {
// throw IOException("Unable to save data in $dbFile for $key : $data")
// } else {
// return
// }
// }
//
// val hasChanged = if (data == null) {
// loadedProps.remove(key) != null
// } else {
// val prev = loadedProps.put(key, data)
// prev !== data
// }
//
// // every time we set info, we want to save it to disk (so the file on disk will ALWAYS be current, and so we can modify it as we choose)
// if (hasChanged) {
// save()
// }
// }
//
// /**
// * Deletes all contents of this storage, and if applicable, it's location on disk.
// */
// override fun deleteAll() {
// if (readOnly) {
// if (readOnlyViolent) {
// throw IOException("Unable to delete all data in $dbFile")
// } else {
// return
// }
// }
//
// loadedProps.clear()
// dbFile.delete()
// }
//
// /**
// * Closes this storage (and if applicable, flushes it's content to disk)
// */
// override fun close() {
// Runtime.getRuntime().removeShutdownHook(thread)
// save()
// }
//}
//
//
import dorkbox.json.JsonException
import dorkbox.json.OutputType
import dorkbox.storage.AccessFunc
import dorkbox.storage.Storage
import mu.KLogger
import java.io.File
import java.io.IOException
import java.util.concurrent.*
/**
* JSON property file storage system
*/
class JsonStore(
val dbFile: File,
val autoLoad: Boolean,
val readOnly: Boolean,
val readOnlyViolent: Boolean,
logger: KLogger,
onLoad: AccessFunc,
onSave: AccessFunc,
) : Storage(logger) {
companion object {
private val comparator = Comparator<Any> { o1, o2 -> o1.toString().compareTo(o2.toString()) }
}
private var version: Long = 0
private val thread = Thread { close() }
private val json = dorkbox.json.Json()
@Volatile
private var lastModifiedTime = 0L
private val loadedProps = ConcurrentHashMap<Any, Any?>()
init {
json.outputType = OutputType.json
load()
val versionInfo = loadedProps[versionTag]
if (versionInfo !is Number) {
loadedProps[versionTag] = version
} else {
setVersion(versionInfo as Long)
}
// Make sure that the timer is run on shutdown. A HARD shutdown will just POW! kill it, a "nice" shutdown will run the hook
Runtime.getRuntime().addShutdownHook(thread)
init("Property file storage initialized at: '$dbFile'")
}
private fun load() {
// if we cannot load, then we create a properties file.
if (!dbFile.canRead() && !dbFile.parentFile.mkdirs() && !dbFile.createNewFile()) {
throw IOException("Cannot create file")
}
try {
synchronized(dbFile) {
@Suppress("UNCHECKED_CAST")
val map = json.fromJson(HashMap::class.java, dbFile) as Map<Any, Any?>?
map?.forEach { (k,v) ->
loadedProps[k] = v
}
lastModifiedTime = dbFile.lastModified()
}
} catch (e: JsonException) {
logger.error("Cannot load JSON file!", e)
} catch (e: IOException) {
logger.error("Cannot load JSON file!", e)
}
}
private fun save() {
if (readOnly) {
// don't accidentally save this!
return
}
// if we cannot save, then we create a NEW properties file. It could have been DELETED out from under us (while in use!)
if (!dbFile.canRead() && !dbFile.parentFile.mkdirs() && !dbFile.createNewFile()) {
throw IOException("Cannot create file")
}
try {
synchronized(dbFile) {
val data = json.toJson(loadedProps)
val pretty = json.prettyPrint(data)
dbFile.writeText(pretty)
lastModifiedTime = dbFile.lastModified()
}
} catch (e: JsonException) {
logger.error("JSON cannot save to: $dbFile", e)
} catch (e: IOException) {
logger.error("JSON cannot save to: $dbFile", e)
}
}
override fun setVersion(version: Long) {
this.version = version
}
override fun file(): File {
return dbFile
}
override fun size(): Int {
return loadedProps.size
}
override fun contains(key: Any): Boolean {
require(key is String) {
"Keys for a json file must be a String"
}
if (autoLoad) {
// we want to check the last modified time when getting, because if we edit the on-disk file, we want to load those changes
val lastModifiedTime = dbFile.lastModified()
if (this.lastModifiedTime != lastModifiedTime) {
// we want to reload the info
load()
}
}
return loadedProps[key] != null
}
override operator fun <V> get(key: Any): V? {
require(key is String) {
"Keys for a json file must be a String"
}
if (autoLoad) {
// we want to check the last modified time when getting, because if we edit the on-disk file, we want to load those changes
val lastModifiedTime = dbFile.lastModified()
if (this.lastModifiedTime != lastModifiedTime) {
// we want to reload the info
load()
}
}
val any = loadedProps[key]
if (any != null) {
@Suppress("UNCHECKED_CAST")
return any as V
}
return null
}
override operator fun set(key: Any, data: Any?) {
require(key is String) {
"Keys for a json file must be a String"
}
if (readOnly) {
if (readOnlyViolent) {
throw IOException("Unable to save data in $dbFile for $key : $data")
} else {
return
}
}
val hasChanged = if (data == null) {
loadedProps.remove(key) != null
} else {
val prev = loadedProps.put(key, data)
prev !== data
}
// every time we set info, we want to save it to disk (so the file on disk will ALWAYS be current, and so we can modify it as we choose)
if (hasChanged) {
save()
}
}
/**
* Deletes all contents of this storage, and if applicable, it's location on disk.
*/
override fun deleteAll() {
if (readOnly) {
if (readOnlyViolent) {
throw IOException("Unable to delete all data in $dbFile")
} else {
return
}
}
loadedProps.clear()
dbFile.delete()
}
/**
* Closes this storage (and if applicable, flushes it's content to disk)
*/
override fun close() {
Runtime.getRuntime().removeShutdownHook(thread)
save()
}
}

View File

@ -2,8 +2,14 @@ module dorkbox.storage {
exports dorkbox.storage;
exports dorkbox.storage.types;
requires transitive dorkbox.byteUtils;
requires transitive dorkbox.json;
requires transitive dorkbox.minlog;
requires transitive dorkbox.objectpool;
requires transitive dorkbox.serializers;
requires transitive dorkbox.updates;
requires transitive com.esotericsoftware.kryo;
requires transitive org.slf4j;
requires transitive io.github.microutils.kotlinlogging;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021 dorkbox, llc
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -227,18 +227,25 @@ class StorageTest {
// @Test
// fun json() {
// val tmp = tmp().newFile()
//// val tmp = tmp().newFile()
// val tmp = File("json.config")
//
// val logger = KotlinLogging.logger("test")
//
// val tester = Tester("key1", "value1")
//
// // lambda's do NOT evaluate equality. Only reference equality.
// val serializer = SerializerBytes {
// register(Tester::class.java, TesterSerializer())
// }
//
// // note: we want to auto-close the storage after we write/read it
// val storage = Storage.Json().file(tmp).register(Tester::class.java, TesterSerializer()).build()
// val storage = Storage.Json().file(tmp).logger(logger).serializer(serializer).build()
// storage.use {
// it["key1"] = tester
// }
//
//
// val storage2 = Storage.Property().file(tmp).register(Tester::class.java, TesterSerializer()).build()
// val storage2 = Storage.Json().file(tmp).logger(logger).serializer(serializer).build()
//
// val tes: Tester? = storage2.use {
// it["key1"]