This commit is contained in:
2024-05-15 19:28:12 +02:00
parent 7677bac1a6
commit c6f84224b1
4 changed files with 50 additions and 27 deletions

View File

@@ -1,3 +1,5 @@
import org.gradle.model.internal.core.ModelNodes.withType
plugins { plugins {
kotlin("jvm") version "2.0.0-RC2" kotlin("jvm") version "2.0.0-RC2"
id("maven-publish") id("maven-publish")
@@ -17,6 +19,9 @@ dependencies {
tasks.test { tasks.test {
useJUnitPlatform() useJUnitPlatform()
minHeapSize = "128m"
maxHeapSize = "1g"
} }
extra["PUBLISH_GROUP_ID"] = group extra["PUBLISH_GROUP_ID"] = group

View File

@@ -201,6 +201,7 @@ class Datastore(
return typeData.data.values return typeData.data.values
.filter { search(it as T) } .filter { search(it as T) }
.map { o -> o.copy() as T } .map { o -> o.copy() as T }
.sortedBy { it.id }
} }
fun findIndex( fun findIndex(
@@ -230,20 +231,21 @@ class Datastore(
private fun writeTransaction(actions: Set<Action>) { private fun writeTransaction(actions: Set<Action>) {
val number = transactionFormatter.format(nextTransactionNumber) val number = transactionFormatter.format(nextTransactionNumber)
val file = File(directory, "transaction-$number.trn") val file = File(directory, "transaction-$number.trn-tmp")
ObjectOutputStream(file.outputStream()).use { oos -> ObjectOutputStream(file.outputStream()).use { oos ->
// version number // version number
oos.writeInt(1) oos.writeInt(1)
oos.writeLong(nextTransactionNumber++) oos.writeLong(nextTransactionNumber++)
oos.writeObject(actions) oos.writeObject(actions)
} }
file.renameTo(File(directory, "transaction-$number.trn"))
} }
fun snapshot() { fun snapshot() {
val start = System.nanoTime() val start = System.nanoTime()
synchronized(this) { synchronized(this) {
val number = transactionFormatter.format(nextTransactionNumber) val number = transactionFormatter.format(nextTransactionNumber)
val file = File(directory, "transaction-$number.snp") val file = File(directory, "transaction-$number.snp-tmp")
ObjectOutputStream(file.outputStream()).use { oos -> ObjectOutputStream(file.outputStream()).use { oos ->
// version number // version number
oos.writeInt(1) oos.writeInt(1)
@@ -259,6 +261,7 @@ class Datastore(
} }
} }
} }
file.renameTo(File(directory, "transaction-$number.snp"))
} }
Logger.debug("Snapshot in %6.3fms", ((System.nanoTime() - start) / 1_000_000f)) Logger.debug("Snapshot in %6.3fms", ((System.nanoTime() - start) / 1_000_000f))
} }

View File

@@ -4,49 +4,51 @@ import java.io.File
import java.io.ObjectInputStream import java.io.ObjectInputStream
class TransactionLog( class TransactionLog(
val directory: File, directory: File,
) { ) {
val fileManager = FileManager(directory) val fileManager = FileManager(directory)
fun showTransactions() { fun showTransactions(printer: (String) -> Unit = ::println) {
fileManager.findLastSnapshot().let { (after, snapshot) -> fileManager.findLastSnapshot().let { (after, snapshot) ->
println("Last snapshot: $snapshot") printer("Last snapshot: $snapshot")
println("Snapshot:") printer("Snapshot:")
snapshot?.inputStream()?.use { input -> snapshot?.inputStream()?.use { input ->
ObjectInputStream(input).use { ois -> ObjectInputStream(input).use { ois ->
val versionNumber = ois.readInt() val versionNumber = ois.readInt()
check(versionNumber == 1) { "Unsupported version number: $versionNumber" } check(versionNumber == 1) {
"Unsupported version number: $versionNumber"
}
val transactionNumber = ois.readLong() val transactionNumber = ois.readLong()
println("[$versionNumber] $transactionNumber") printer("[$versionNumber] $transactionNumber")
val data = ois.readObject() as MutableMap<Class<*>, TypeData> val data = ois.readObject() as MutableMap<Class<*>, TypeData>
println("Data:") printer("Data:")
println("\tClasses:") printer("\tClasses:")
for ((cls, entries) in data.entries) { for ((cls, entries) in data.entries) {
println("\t\t- $cls: ${entries.data.keys.size}") printer("\t\t- $cls: ${entries.data.keys.size}")
} }
} }
} }
val transactions = fileManager.findTransactionsAfter(after ?: 0L) val transactions = fileManager.findTransactionsAfter(after ?: 0L)
println("Transactions:") printer("Transactions:")
transactions?.forEach { transaction -> transactions?.forEach { transaction ->
transaction.inputStream().use { input -> transaction.inputStream().use { input ->
ObjectInputStream(input).use { ois -> ObjectInputStream(input).use { ois ->
val versionNumber = ois.readInt() val versionNumber = ois.readInt()
check(versionNumber == 1) { "Unsupported version number: $versionNumber" } check(versionNumber == 1) {
"Unsupported version number: $versionNumber"
}
val transactionNumber = ois.readLong() val transactionNumber = ois.readLong()
val actions = ois.readObject() as Set<Action> val actions = ois.readObject() as Set<Action>
println("\t[$transactionNumber]") printer("\t[$transactionNumber]")
for (action in actions) { for (action in actions) {
println("\t\t- $action") printer("\t\t- $action")
} }
} }
} }
} }
} }
} }
}
}

View File

@@ -5,6 +5,7 @@ import nl.astraeus.persistence.domain.Person
import java.io.File import java.io.File
import kotlin.random.Random import kotlin.random.Random
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals
class TestThreaded { class TestThreaded {
@@ -42,6 +43,7 @@ class TestThreaded {
person.name to person.age person.name to person.age
} }
}, },
index<Person>("personCompanyId") { p -> (p as? Person)?.company?.id ?: 0L },
index<Company>("name") { p -> (p as? Company)?.name ?: "" }, index<Company>("name") { p -> (p as? Company)?.name ?: "" },
) )
) )
@@ -68,7 +70,7 @@ class TestThreaded {
name = names[random.nextInt(names.size)], name = names[random.nextInt(names.size)],
age = random.nextInt(0, 100), age = random.nextInt(0, 100),
) )
//person.company = company person.company = company
store(person) store(person)
} }
@@ -80,6 +82,7 @@ class TestThreaded {
Thread(runnable) Thread(runnable)
} }
val start = System.nanoTime()
for (thread in threads) { for (thread in threads) {
thread.start() thread.start()
} }
@@ -87,19 +90,29 @@ class TestThreaded {
for (thread in threads) { for (thread in threads) {
thread.join() thread.join()
} }
println("Store elapsed time: ${(System.nanoTime() - start) / 1_000_000}ms")
} }
pst.query { var start = 0L
searchIndex<Person>("nameAndAge") { nameAndAge -> repeat(10) {
val (name, age) = nameAndAge as Pair<String, Int> start = System.nanoTime()
val withoutIndex = pst.query {
name.contains("mit") && age > 80 search<Person> { person ->
}.forEach { p -> person.age == 20
println("Found person by name and age: ${p.id}: ${p.name} - ${p.age}") }
} }
println("withoutIndex elapsed time: ${(System.nanoTime() - start) / 1_000_000f}ms")
start = System.nanoTime()
val withIndex = pst.query {
searchIndex<Person>("age") { age -> (age as? Int ?: -1) == 20 }
}
println("withIndex elapsed time: ${(System.nanoTime() - start) / 1_000_000f}ms")
assertEquals(withIndex.size, withoutIndex.size)
} }
//pst.snapshot() pst.snapshot()
pst.datastore.printStatus() pst.datastore.printStatus()
pst.removeOldFiles() pst.removeOldFiles()
} }