Skip to content

Commit

Permalink
make some progress
Browse files Browse the repository at this point in the history
Signed-off-by: Kengo TODA <skypencil@gmail.com>
  • Loading branch information
KengoTODA committed Nov 19, 2023
1 parent 25c22fd commit e16665d
Show file tree
Hide file tree
Showing 23 changed files with 228 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Kosmo

[![Continuous Integration](https://github.com/KengoTODA/kosmo/actions/workflows/ci.yaml/badge.svg)](https://github.com/KengoTODA/kosmo/actions/workflows/ci.yaml)

Kosmo is a simple Relational Database implemented in Kotlin.
This product is not developed for production use, just for personal learning.

## Architecture

```mermaid
graph TD
subgraph frontend
main-process --> cpf[connection pool]
subgraph worker
worker-process -->
optimizer -->
rewriter -->
planner --> worker-process
end
main-process --> worker-process
worker-process --> al[(audit-log)]
end
subgraph backend
coordinator-process --> cpb[connection pool]
subgraph database
database-process
wal[(write ahead log)]
subgraph storage-engine
table --> df[(data file)]
index --> df
vacuumer --> df
end
database-process --> wal
database-process --> table
database-process --> index
database-process --> vacuumer
end
end
subgraph replica
wal --> replica-process
end
client --> main-process
worker-process --> coordinator-process --> database-process
```
8 changes: 7 additions & 1 deletion backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@ plugins {
}

application {
mainClass.set("jp.skypencil.kosmo.backend.AppKt")
mainClass = "jp.skypencil.kosmo.backend.Coordinator"
}

dependencies {
implementation(libs.slf4j.api)
implementation(libs.uuid.creator)
runtimeOnly(libs.log4j.slf4j2.impl)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package jp.skypencil.kosmo.backend

import jp.skypencil.kosmo.backend.storage.onmemory.OnMemoryDatabase
import jp.skypencil.kosmo.backend.wal.LogWriter

/**
* フロントエンドからの要求を受け取り、それぞれのクラスを組み合わせて実現する。
*/
class Coordinator {
}
private val database = OnMemoryDatabase()
private val logWriter = LogWriter()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package jp.skypencil.kosmo.backend.storage.onmemory

import jp.skypencil.kosmo.backend.storage.shared.Table
import jp.skypencil.kosmo.backend.storage.shared.Database

class OnMemoryDatabase : Database {
private val tables = mutableMapOf<String, OnMemoryTable>()
override suspend fun findTable(name: String): Table =
checkNotNull(tables[name])

override suspend fun createTable(name: String): Table {
require(!tables.containsKey(name))
return OnMemoryTable(name).also {
tables[name] = it
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package jp.skypencil.kosmo.backend.storage.onmemory

import jp.skypencil.kosmo.backend.storage.shared.Table
import jp.skypencil.kosmo.backend.value.Row
import jp.skypencil.kosmo.backend.value.RowId
import jp.skypencil.kosmo.backend.value.TransactionId
import kotlin.streams.asSequence

// TODO トランザクション
// TODO スレッドセーフティ
class OnMemoryTable(private val name: String) : Table {
private val map = mutableMapOf<RowId, Row>()

override fun getName(): String = name

override suspend fun find(transactionId: TransactionId, id: RowId): Row = checkNotNull(map[id])

override suspend fun tableScan(transactionId: TransactionId): Sequence<Row> = map.values.stream().asSequence()

override suspend fun insert(transactionId: TransactionId, row: Row) {
check(map[row.id] == null)
map[row.id] = row
}

override suspend fun delete(transactionId: TransactionId, id: RowId): Boolean = map.remove(id) != null

override suspend fun update(transactionId: TransactionId, row: Row) {
checkNotNull(map[row.id])
map[row.id] = row
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package jp.skypencil.kosmo.backend.storage.shared

interface Database {
suspend fun findTable(name: String): Table
suspend fun createTable(name: String): Table
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package jp.skypencil.kosmo.backend.storage.shared

import jp.skypencil.kosmo.backend.value.Row
import jp.skypencil.kosmo.backend.value.RowId

/**
* データや索引の管理を抽象化する。
*/
interface StorageEngine {
suspend fun find(id: RowId): Row
suspend fun tableScan(): Sequence<Row>
suspend fun indexScan(): Sequence<Row>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package jp.skypencil.kosmo.backend.storage.shared

import jp.skypencil.kosmo.backend.value.Row
import jp.skypencil.kosmo.backend.value.RowId
import jp.skypencil.kosmo.backend.value.TransactionId

interface Table {
fun getName(): String

suspend fun find(tx: TransactionId, id: RowId): Row
suspend fun tableScan(tx: TransactionId): Sequence<Row>
suspend fun insert(tx: TransactionId, row: Row)
suspend fun delete(tx: TransactionId, id: RowId): Boolean
suspend fun update(tx: TransactionId, row: Row)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package jp.skypencil.kosmo.backend.value

/**
* データベースの変更を表す。
*/
interface LogEntry {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package jp.skypencil.kosmo.backend.value

data class Row(val id: RowId) {
}
15 changes: 15 additions & 0 deletions backend/src/main/kotlin/jp/skypencil/kosmo/backend/value/RowId.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package jp.skypencil.kosmo.backend.value

import java.util.UUID

data class RowId(private val uuid: UUID): Comparable<RowId> {
init {
check(uuid.version() == 6) {
"RowIdはTime-basedなUUIDである必要があります"
}
}

override fun compareTo(other: RowId): Int =
this.uuid.compareTo(other.uuid)

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package jp.skypencil.kosmo.backend.value

class TransactionId {
}
import com.github.f4b6a3.uuid.UuidCreator
import java.util.UUID

class TransactionId(private val uuid: UUID): Comparable<TransactionId> {
companion object {
fun create() = TransactionId(UuidCreator.getTimeOrdered())
}

override fun compareTo(other: TransactionId): Int = uuid.compareTo(other.uuid)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package jp.skypencil.kosmo.backend.wal

import jp.skypencil.kosmo.backend.value.LogEntry

/**
* Write Ahead Log(WAL)を記録する責務を負う。
*/
class LogWriter {
suspend fun write(logEntry: LogEntry) {

}
}
2 changes: 2 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ plugins {
}

repositories {
mavenCentral()
gradlePluginPortal()
}

dependencies {
implementation("com.diffplug.spotless:spotless-plugin-gradle:6.22.0")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10")
}
14 changes: 8 additions & 6 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This settings file is used to specify which projects to include in your build-logic build.
*/

rootProject.name = "buildSrc"

dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id("org.jetbrains.kotlin.jvm")
id("com.diffplug.spotless")
}

repositories {
Expand All @@ -12,6 +13,17 @@ java {
}
}

val kotest = "5.8.0"
dependencies {
testImplementation("io.kotest:kotest-assertions-core:$kotest")
testImplementation("io.kotest:kotest-property:$kotest")
testRuntimeOnly("io.kotest:kotest-runner-junit5:$kotest")
}

tasks.named<Test>("test") {
useJUnitPlatform()
}

tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.gradle.parallel=true
org.gradle.caching=true
10 changes: 10 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[versions]
kotest = "5.8.0"
log4j = "2.20.0"
slf4j = "2.0.9"

[libraries]
kotest-runner-juni5 = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
log4j-slf4j2-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" }
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
uuid-creator = { module = "com.github.f4b6a3:uuid-creator", version = "5.3.3" }
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ plugins {
}

rootProject.name = "kosmo"
include("backend", "frontend", "jdbc-driver")
include("backend", "frontend")
File renamed without changes.

0 comments on commit e16665d

Please sign in to comment.