Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralph Gasser committed Apr 24, 2024
2 parents 5175be8 + 10f74e0 commit 5f77827
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 7 deletions.
85 changes: 85 additions & 0 deletions cottontaildb-core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,88 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

apply plugin: 'maven-publish'
apply plugin: 'signing'

repositories {
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}

/** Source & target compatibility is Java 11. */
sourceCompatibility = 11
targetCompatibility = 11

compileKotlin {
compilerOptions.jvmTarget = JvmTarget.JVM_11
}

compileTestKotlin {
compilerOptions.jvmTarget = JvmTarget.JVM_11
}

java {
withJavadocJar()
withSourcesJar()
}

configurations {
clientLibrary {
canBeConsumed = true
canBeResolved = false
}
}

publishing {
publications {
mavenJava(MavenPublication) {
groupId = 'org.vitrivr'
artifactId = 'cottontaildb-core'
version = System.getenv().getOrDefault("MAVEN_PUBLICATION_VERSION", version.toString())
pom {
name = 'Cottontail DB Core Library'
description = 'The Cottontail DB core library, which is a collection of classes that are used by different Cottontail DB components.'
url = 'https://github.com/vitrivr/cottontaildb/'
licenses {
license {
name = 'MIT License'
}
}
developers {
developer {
id = 'ppanopticon'
name = 'Ralph Gasser'
email = '[email protected]'
}
}
scm {
connection = 'scm:git:https://github.com/vitrivr/cottontaildb.git'
url = 'https://github.com/vitrivr/cottontaildb'
}
}
from components.java
}
}
repositories {
maven {
def releasesRepoUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
def snapshotsRepoUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
name = "OSSRH"
url = (publishing.publications.mavenJava.version.endsWith('SNAPSHOT')) ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username = System.getenv("MAVEN_USERNAME")
password = System.getenv("MAVEN_PASSWORD")
}
}
}
}

signing {
def signingKey = findProperty("signingKey")
def signingPassword = findProperty("signingPassword")
useInMemoryPgpKeys(signingKey, signingPassword)
sign publishing.publications.mavenJava
}

dependencies {
/* The Cottontail DB client library. */
api project(':cottontaildb-client')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.vitrivr.cottontail.dbms.general.DBOVersion
import org.vitrivr.cottontail.dbms.index.basic.*
import org.vitrivr.cottontail.dbms.queries.context.QueryContext
import org.vitrivr.cottontail.dbms.schema.DefaultSchema
import org.vitrivr.cottontail.dbms.sequence.DefaultSequence
import kotlin.concurrent.withLock

/**
Expand All @@ -33,7 +34,7 @@ import kotlin.concurrent.withLock
* @see EntityTx
*
* @author Ralph Gasser
* @version 4.0.0
* @version 4.0.1
*/
class DefaultEntity(override val name: Name.EntityName, override val parent: DefaultSchema) : Entity {

Expand All @@ -54,15 +55,26 @@ class DefaultEntity(override val name: Name.EntityName, override val parent: Def
override fun newTx(context: QueryContext): EntityTx
= context.txn.getCachedTxForDBO(this) ?: this.Tx(context)

/**
* Compares this [DefaultSchema] to another [Any].
*
* @param other [Any] object or null
* @return True if equal, false otherwise.
*/
override fun equals(other: Any?): Boolean {
if (other !is DefaultEntity) return false
if (other.catalogue != this.catalogue) return false
if (other.parent != this.parent) return false
return other.name == this.name
}

/**
* Generates a hash code for this [DefaultSequence]
*
* @return Hash code.
*/
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + parent.hashCode()
var result = this.name.hashCode()
result = 31 * result + this.parent.hashCode()
return result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ class DefaultSchema(override val name: Name.SchemaName, override val parent: Def
override fun newTx(context: QueryContext): SchemaTx
= context.txn.getCachedTxForDBO(this) ?: this.Tx(context)

/**
* Compares this [DefaultSchema] to another [Any].
*
* @param other [Any] object or null
* @return True if equal, false otherwise.
*/
override fun equals(other: Any?): Boolean {
if (other !is DefaultSchema) return false
if (other.parent != this.parent) return false
return other.name == this.name
}

/**
* Generates a hash code for this [DefaultSequence]
*
* @return Hash code.
*/
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + parent.hashCode()
return result
}

/**
* A [Tx] that affects this [DefaultSchema].
*
Expand Down Expand Up @@ -156,7 +179,7 @@ class DefaultSchema(override val name: Name.SchemaName, override val parent: Def

/* Create sequence. */
if (it.second.autoIncrement) {
this.createSequence(this@DefaultSchema.name.sequence("${it.first.entity}_${it.first.column}_auto"))
this.createSequence(it.first.autoincrement()!!)
}

/* Create store for column data. */
Expand Down Expand Up @@ -232,7 +255,7 @@ class DefaultSchema(override val name: Name.SchemaName, override val parent: Def
entityTx.listColumns().forEach {
this@DefaultSchema.catalogue.transactionManager.environment.truncateStore("${name.storeName()}#bitmap", this.context.txn.xodusTx)
if (it.autoIncrement) {
val sequenceTx = this.sequenceForName(this@DefaultSchema.name.sequence("${it.name.entity}_${it.name.column}_auto")).newTx(this.context)
val sequenceTx = this.sequenceForName(it.name.autoincrement()!!).newTx(this.context)
sequenceTx.reset()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicLong
* @see SequenceTx
*
* @author Ralph Gasser
* @version 3.1.0
* @version 3.1.1
*/
class DefaultSequence(override val name: Name.SequenceName, override val parent: DefaultSchema): Sequence {
companion object {
Expand Down Expand Up @@ -68,10 +68,37 @@ class DefaultSequence(override val name: Name.SequenceName, override val parent:
override fun newTx(context: QueryContext): SequenceTx
= context.txn.getCachedTxForDBO(this) ?: this.Tx(context)

/**
* Compares this [DefaultSequence] to another [Any].
*
* @param other [Any] object or null
* @return True if equal, false otherwise.
*/
override fun equals(other: Any?): Boolean {
if (other !is DefaultSequence) return false
if (other.parent != this.parent) return false
return other.name == this.name
}

/**
* Generates a hash code for this [DefaultSequence]
*
* @return Hash code.
*/
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + parent.hashCode()
return result
}

/**
* A [Tx] that affects this [DefaultEntity].
*/
inner class Tx(context: QueryContext): AbstractTx(context), SequenceTx, org.vitrivr.cottontail.dbms.general.Tx.WithCommitFinalization {
init {
/* Cache this Tx for future use. */
context.txn.cacheTx(this)
}

/** Reference to the surrounding [DefaultEntity]. */
override val dbo: DBO
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.vitrivr.cottontail.dbms.entity.sequence

import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.vitrivr.cottontail.core.tuple.StandaloneTuple
import org.vitrivr.cottontail.core.types.Value
import org.vitrivr.cottontail.core.values.IntValue
import org.vitrivr.cottontail.core.values.LongValue
import org.vitrivr.cottontail.core.values.generators.StringValueGenerator
import org.vitrivr.cottontail.dbms.entity.AbstractEntityTest
import org.vitrivr.cottontail.dbms.execution.transactions.TransactionType
import org.vitrivr.cottontail.dbms.queries.context.DefaultQueryContext
import org.vitrivr.cottontail.test.TestConstants
import java.util.*

/**
* An abstract class for test cases that test for correctness of sequences
*
* @author Ralph Gasser
* @version 1.0.0
*/
abstract class AbstractSequenceTest: AbstractEntityTest() {
/** [SplittableRandom] used to generate random values. */
protected val random = SplittableRandom()

@Test
fun testSequence() {
val txn1 = this.manager.startTransaction(TransactionType.SYSTEM_EXCLUSIVE)
val ctx1 = DefaultQueryContext("test-sequence-insert", this.catalogue, txn1)

/* Insert all entries. */
val catalogueTx1 = this.catalogue.newTx(ctx1)
val schema1 = catalogueTx1.schemaForName(this.schemaName)
val schemaTx1 = schema1.newTx(ctx1)
val entity1 = schemaTx1.entityForName(TestConstants.TEST_ENTITY_NAME)
val entityTx1 = entity1.newTx(ctx1)
repeat(TestConstants.TEST_COLLECTION_SIZE - 1) {
entityTx1.insert(this.nextRecord())
}
txn1.commit()

/* Iterate over entries and read IDs. */
val txn2 = this.manager.startTransaction(TransactionType.USER_READONLY)
val ctx2 = DefaultQueryContext("test-sequence-read", this.catalogue, txn2)

/* Insert all entries. */
val catalogueTx2 = this.catalogue.newTx(ctx2)
val schema2 = catalogueTx2.schemaForName(this.schemaName)
val schemaTx2 = schema2.newTx(ctx2)
val entity2 = schemaTx2.entityForName(TestConstants.TEST_ENTITY_NAME)
val entityTx2 = entity2.newTx(ctx2)
val cursor = entityTx2.cursor(this.entities[0].second.toTypedArray())
for ((i, record) in cursor.withIndex()) {
test(record[this.entities[0].second[0]], i)
}
txn2.commit()
}

/** We start with an empty entity. */
override fun populateDatabase() {
/* No op */
}

/**
* Generates the next [StandaloneTuple] and returns it.
*/
fun nextRecord(): StandaloneTuple {
val string = StringValueGenerator.random(this.random)
return StandaloneTuple(0L, columns = arrayOf(this.entities[0].second[1]), values = arrayOf(string))
}

abstract fun test(value: Value?, index: Int)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.vitrivr.cottontail.dbms.entity.sequence

import org.junit.jupiter.api.Assertions
import org.vitrivr.cottontail.core.database.ColumnDef
import org.vitrivr.cottontail.core.database.Name
import org.vitrivr.cottontail.core.types.Types
import org.vitrivr.cottontail.core.types.Value
import org.vitrivr.cottontail.core.values.IntValue
import org.vitrivr.cottontail.test.TestConstants

class IntSequenceTest: AbstractSequenceTest() {
/** The test entity. */
override val entities: List<Pair<Name.EntityName, List<ColumnDef<*>>>> = listOf(
TestConstants.TEST_ENTITY_NAME to listOf(
ColumnDef(TestConstants.TEST_ENTITY_NAME.column(TestConstants.ID_COLUMN_NAME), Types.Int, nullable = false, primary = true, autoIncrement = true),
ColumnDef(TestConstants.TEST_ENTITY_NAME.column(TestConstants.STRING_COLUMN_NAME), Types.String, nullable = false, primary = false, autoIncrement = false),
)
)

override fun test(value: Value?, index: Int) = Assertions.assertEquals(index+1, (value as? IntValue)!!.value)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.vitrivr.cottontail.dbms.entity.sequence

import org.junit.jupiter.api.Assertions
import org.vitrivr.cottontail.core.database.ColumnDef
import org.vitrivr.cottontail.core.database.Name
import org.vitrivr.cottontail.core.types.Types
import org.vitrivr.cottontail.core.types.Value
import org.vitrivr.cottontail.core.values.LongValue
import org.vitrivr.cottontail.test.TestConstants

class LongSequenceTest: AbstractSequenceTest() {
/** The test entity. */
override val entities: List<Pair<Name.EntityName, List<ColumnDef<*>>>> = listOf(
TestConstants.TEST_ENTITY_NAME to listOf(
ColumnDef(TestConstants.TEST_ENTITY_NAME.column(TestConstants.ID_COLUMN_NAME), Types.Long, nullable = false, primary = true, autoIncrement = true),
ColumnDef(TestConstants.TEST_ENTITY_NAME.column(TestConstants.STRING_COLUMN_NAME), Types.String, nullable = false, primary = false, autoIncrement = false),
)
)

override fun test(value: Value?, index: Int) = Assertions.assertEquals(index+1L, (value as? LongValue)!!.value)
}

0 comments on commit 5f77827

Please sign in to comment.