Skip to content

Commit

Permalink
Merged
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralph Gasser committed Aug 26, 2024
2 parents eaa3821 + a60e978 commit 02dfef1
Show file tree
Hide file tree
Showing 60 changed files with 1,820 additions and 512 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id 'org.jetbrains.kotlin.jvm' version "$version_kotlin"
id 'org.jetbrains.kotlin.plugin.serialization' version "$version_kotlin"
id 'org.openapi.generator' version '7.4.0'
id "de.undercouch.download" version "5.4.0"
id 'org.openapi.generator' version '7.8.0'
id 'de.undercouch.download' version "5.6.0"
id 'java-library'
id 'idea'
}
Expand Down
34 changes: 16 additions & 18 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
version_boofcv=1.1.5
version_caffeine=3.1.8
version_clikt=4.2.0
version_clikt=4.2.2
version_commonsmath3=3.6.1
version_cottontaildb=0.16.1
version_javacv=1.5.9
version_javalin=6.1.3
version_javalinopenapi=6.1.3
version_javalinssl=6.1.3
version_jdbc_postgres=42.7.3
version_jline=3.23.0
version_junit=5.10.1
version_junit_platform=1.10.1
version_grpc=1.60.0
version_kotlin=1.9.21
version_cottontaildb=0.16.7
version_javacv=1.5.10
version_javalin=6.3.0
version_jdbc_postgres=42.7.4
version_jline=3.26.3
version_junit=5.11.0
version_junit_platform=1.11.0
version_grpc=1.66.0
version_kotlin=1.9.25
version_kotlinx_coroutines=1.7.3
version_kotlinx_serialization=1.6.2
version_kotlinx_datetime=0.4.1
version_kotlinlogging = 5.1.0
version_lwjgl=3.3.4
version_log4j2=2.20.0
version_log4j2=2.23.1
version_metadataextractor=2.19.0
version_okhttp3=4.12.0
version_picnic=0.7.0
version_protobuf=3.25.1
version_scrimage=4.1.1
version_slf4j=2.0.9
version_protobuf=4.27.3
version_scrimage=4.2.0
version_slf4j=2.0.16
version_jogl=2.3.2
version_joml=1.9.25
version_ktor=2.3.6
version_ktor=2.3.12
2 changes: 1 addition & 1 deletion vitrivr-engine-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
dependencies {
/** dependencies for exif metadata extraction. */
implementation group: 'com.drewnoakes', name: 'metadata-extractor', version: version_metadataextractor
implementation group: 'io.javalin.community.openapi', name: 'javalin-openapi-plugin', version: version_javalinopenapi
implementation group: 'io.javalin.community.openapi', name: 'javalin-openapi-plugin', version: version_javalin

/* Test Fixtures from Cottontail DB core. .*/
testFixturesImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: version_junit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class BlackholeConnectionProvider : ConnectionProvider {
override val databaseName: String = "blackhole"
override val version: String = "1.0.0"
override fun openConnection(schemaName: String, parameters: Map<String, String>) = BlackholeConnection(schemaName, this, parameters["log"]?.toBoolean() == true)
override fun <T : Descriptor<*>> register(descriptorClass: KClass<T>, provider: DescriptorProvider<*>) { /* No op. */ }
override fun <T : Descriptor<*>> register(descriptorClass: KClass<T>, provider: DescriptorProvider<*>) { /* No op. */
}

override fun <T : Descriptor<*>> obtain(descriptorClass: KClass<T>) = BlackholeDescriptionProvider<T>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import org.vitrivr.engine.core.model.metamodel.Schema
* @author Ralph Gasser
* @version 1.0.0
*/
class BlackholeDescriptionProvider<T: Descriptor<*>>: DescriptorProvider<T> {
override fun newInitializer(connection: Connection, field: Schema.Field<*, T>)= BlackholeDescriptorInitializer(connection as BlackholeConnection, field)
class BlackholeDescriptionProvider<T : Descriptor<*>> : DescriptorProvider<T> {
override fun newInitializer(connection: Connection, field: Schema.Field<*, T>) = BlackholeDescriptorInitializer(connection as BlackholeConnection, field)
override fun newReader(connection: Connection, field: Schema.Field<*, T>): DescriptorReader<T> = BlackholeDescriptorReader(connection as BlackholeConnection, field)
override fun newWriter(connection: Connection, field: Schema.Field<*, T>): DescriptorWriter<T> = BlackholeDescriptorWriter(connection as BlackholeConnection, field)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.vitrivr.engine.core.model.metamodel.Schema
* @author Ralph Gasser
* @version 1.0.0
*/
class BlackholeDescriptorInitializer<T: Descriptor<*>>(private val connection: BlackholeConnection, override val field: Schema.Field<*, T>): DescriptorInitializer<T> {
class BlackholeDescriptorInitializer<T : Descriptor<*>>(private val connection: BlackholeConnection, override val field: Schema.Field<*, T>) : DescriptorInitializer<T> {
override fun initialize() = this.connection.logIf("Initializing descriptor entity '${this.field.fieldName}'.")
override fun deinitialize() = this.connection.logIf("De-initializing descriptor entity '${this.field.fieldName}'.")
override fun isInitialized(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import org.vitrivr.engine.core.model.retrievable.Retrieved
* @author Ralph Gasser
* @version 1.0.0
*/
class BlackholeDescriptorReader<T: Descriptor<*>>(override val connection: BlackholeConnection, override val field: Schema.Field<*, T>) : DescriptorReader<T> {
class BlackholeDescriptorReader<T : Descriptor<*>>(override val connection: BlackholeConnection, override val field: Schema.Field<*, T>) : DescriptorReader<T> {
override fun exists(descriptorId: DescriptorId): Boolean = false
override fun get(descriptorId: DescriptorId): T? = null
override fun getAll(descriptorIds: Iterable<DescriptorId>) = emptySequence<T>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.vitrivr.engine.core.model.metamodel.Schema
* @author Ralph Gasser
* @version 1.0.0
*/
class BlackholeDescriptorWriter<T: Descriptor<*>>(override val connection: BlackholeConnection, override val field: Schema.Field<*, T>): DescriptorWriter<T> {
class BlackholeDescriptorWriter<T : Descriptor<*>>(override val connection: BlackholeConnection, override val field: Schema.Field<*, T>) : DescriptorWriter<T> {
override fun add(item: T): Boolean {
this.connection.logIf("Adding descriptor '${item.id}' to entity '${this.field.fieldName}'.")
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.vitrivr.engine.core.database.retrievable.RetrievableInitializer
* @author Ralph Gasser
* @version 1.0.0
*/
class BlackholeRetrievableInitializer(private val connection: BlackholeConnection): RetrievableInitializer {
class BlackholeRetrievableInitializer(private val connection: BlackholeConnection) : RetrievableInitializer {
override fun initialize() = this.connection.logIf("Initializing entities 'retrievable' and 'relationship'.")
override fun deinitialize() = this.connection.logIf("De-initializing entities 'retrievable' and 'relationship'.")
override fun isInitialized(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.vitrivr.engine.core.model.retrievable.RetrievableId
*/
class BlackholeRetrievableReader(override val connection: BlackholeConnection) : RetrievableReader {
override fun get(id: RetrievableId): Retrievable? = null
override fun exists(id: RetrievableId): Boolean = false
override fun exists(id: RetrievableId): Boolean = false
override fun getAll(ids: Iterable<RetrievableId>) = emptySequence<Retrievable>()
override fun getAll() = emptySequence<Retrievable>()
override fun getConnections(subjectIds: Collection<RetrievableId>, predicates: Collection<String>, objectIds: Collection<RetrievableId>) = emptySequence<Triple<RetrievableId, String, RetrievableId>>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import org.vitrivr.engine.core.model.retrievable.Retrievable
* @author Ralph Gasser
* @version 1.0.0
*/
class BlackholeRetrievableWriter(override val connection: BlackholeConnection): RetrievableWriter {
class BlackholeRetrievableWriter(override val connection: BlackholeConnection) : RetrievableWriter {
override fun connect(relationship: Relationship): Boolean {
this.connection.logIf("Adding relationship ${relationship.subjectId} >[${relationship.predicate}] ${relationship.objectId}.")
return false
}

override fun connectAll(relationships: Iterable<Relationship>): Boolean {
relationships.forEach { relationship -> this.connection.logIf("Adding relationship ${relationship.subjectId} >[${relationship.predicate}] ${relationship.objectId}.")}
relationships.forEach { relationship -> this.connection.logIf("Adding relationship ${relationship.subjectId} >[${relationship.predicate}] ${relationship.objectId}.") }
return false
}

Expand All @@ -29,7 +29,7 @@ class BlackholeRetrievableWriter(override val connection: BlackholeConnection):
}

override fun disconnectAll(relationships: Iterable<Relationship>): Boolean {
relationships.forEach { relationship -> this.connection.logIf("Removing relationship ${relationship.subjectId} >[${relationship.predicate}] ${relationship.objectId}.")}
relationships.forEach { relationship -> this.connection.logIf("Removing relationship ${relationship.subjectId} >[${relationship.predicate}] ${relationship.objectId}.") }
return false
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.vitrivr.engine.core.features

import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
Expand All @@ -20,13 +22,16 @@ import org.vitrivr.engine.core.operators.retrieve.Retriever
* @see [AbstractRetriever]
*
* @author Rahel Arnold
* @version 1.0.0
* @version 1.0.1
*/
abstract class AbstractRetriever<C : ContentElement<*>, D : Descriptor<*>>(override val field: Schema.Field<C, D>, val query: Query, val context: QueryContext) : Retriever<C, D> {

/** The [DescriptorReader] instance used by this [AbstractRetriever]. */
protected val reader: DescriptorReader<D> by lazy { this.field.getReader() }

/** The [KLogger] instance used by this [AbstractRetriever]. */
protected val logger: KLogger = KotlinLogging.logger {}

/**
* Simplest implementation of the retrieval logic simply hand the [Query] to the [DescriptorReader] and emit the results.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package org.vitrivr.engine.core.features.averagecolor

import org.vitrivr.engine.core.context.IndexContext
import org.vitrivr.engine.core.context.QueryContext
import org.vitrivr.engine.core.model.color.MutableRGBFloatColorContainer
import org.vitrivr.engine.core.model.color.RGBByteColorContainer
import org.vitrivr.engine.core.model.color.RGBFloatColorContainer
import org.vitrivr.engine.core.features.dense.DenseRetriever
import org.vitrivr.engine.core.math.correspondence.LinearCorrespondence
import org.vitrivr.engine.core.model.color.RGBColorContainer
import org.vitrivr.engine.core.model.content.Content
import org.vitrivr.engine.core.model.content.element.ImageContent
import org.vitrivr.engine.core.model.descriptor.vector.FloatVectorDescriptor
Expand All @@ -30,28 +30,9 @@ import java.util.*
* @version 1.0.0
*/
class AverageColor : Analyser<ImageContent, FloatVectorDescriptor> {

override val contentClasses = setOf(ImageContent::class)
override val descriptorClass = FloatVectorDescriptor::class

companion object {
/**
* Performs the [AverageColor] analysis on the provided [List] of [ImageContent] elements.
*
* @param content The [List] of [ImageContent] elements.
* @return [List] of [FloatVectorDescriptor]s.
*/
fun analyse(content: Collection<ImageContent>): List<FloatVectorDescriptor> = content.map {
val color = MutableRGBFloatColorContainer()
val rgb = it.content.getRGBArray()
rgb.forEach { c -> color += RGBByteColorContainer(c) }

/* Generate descriptor. */
val averageColor = RGBFloatColorContainer(color.red / rgb.size, color.green / rgb.size, color.blue / rgb.size)
FloatVectorDescriptor(UUID.randomUUID(), null, averageColor.toVector())
}
}

/**
* Generates a prototypical [FloatVectorDescriptor] for this [AverageColor].
*
Expand Down Expand Up @@ -85,33 +66,30 @@ class AverageColor : Analyser<ImageContent, FloatVectorDescriptor> {
override fun newExtractor(name: String, input: Operator<Retrievable>, context: IndexContext): Extractor<ImageContent, FloatVectorDescriptor> = AverageColorExtractor(input, this, null)

/**
* Generates and returns a new [AverageColorRetriever] instance for this [AverageColor].
* Generates and returns a new [DenseRetriever] instance for this [AverageColor].
*
* @param field The [Schema.Field] to create an [Retriever] for.
* @param query The [Query] to use with the [Retriever].
* @param context The [QueryContext] to use with the [Retriever].
*
* @return A new [Retriever] instance for this [Analyser]
*/
override fun newRetrieverForQuery(field: Schema.Field<ImageContent, FloatVectorDescriptor>, query: Query, context: QueryContext): AverageColorRetriever {
require(field.analyser == this) { "The field '${field.fieldName}' analyser does not correspond with this analyser. This is a programmer's error!" }
override fun newRetrieverForQuery(field: Schema.Field<ImageContent, FloatVectorDescriptor>, query: Query, context: QueryContext): DenseRetriever<ImageContent> {
require(query is ProximityQuery<*> && query.value is Value.FloatVector) { "The query is not a ProximityQuery<Value.FloatVector>." }
@Suppress("UNCHECKED_CAST")
return AverageColorRetriever(field, query as ProximityQuery<Value.FloatVector>)
return DenseRetriever(field, query as ProximityQuery<Value.FloatVector>, context, LinearCorrespondence(3f))
}

/**
* Generates and returns a new [AverageColorRetriever] instance for this [AverageColor].
* Generates and returns a new [DenseRetriever] instance for this [AverageColor].
*
* Invoking this method involves converting the provided [FloatVectorDescriptor] into a [ProximityQuery] that can be used to retrieve similar [ImageContent] elements.
*
* @param field The [Schema.Field] to create an [Retriever] for.
* @param descriptors An array of [FloatVectorDescriptor] elements to use with the [Retriever]
* @param context The [QueryContext] to use with the [Retriever]
*/
override fun newRetrieverForDescriptors(field: Schema.Field<ImageContent, FloatVectorDescriptor>, descriptors: Collection<FloatVectorDescriptor>, context: QueryContext): AverageColorRetriever {
require(field.analyser == this) { "The field '${field.fieldName}' analyser does not correspond with this analyser. This is a programmer's error!" }

override fun newRetrieverForDescriptors(field: Schema.Field<ImageContent, FloatVectorDescriptor>, descriptors: Collection<FloatVectorDescriptor>, context: QueryContext): DenseRetriever<ImageContent> {
/* Prepare query parameters. */
val k = context.getProperty(field.fieldName, "limit")?.toLongOrNull() ?: 1000L
val fetchVector = context.getProperty(field.fieldName, "returnDescriptor")?.toBooleanStrictOrNull() ?: false
Expand All @@ -121,7 +99,7 @@ class AverageColor : Analyser<ImageContent, FloatVectorDescriptor> {
}

/**
* Generates and returns a new [AverageColorRetriever] instance for this [AverageColor].
* Generates and returns a new [DenseRetriever] instance for this [AverageColor].
*
* Invoking this method involves converting the provided [ImageContent] and the [QueryContext] into a [FloatVectorDescriptor]
* that can be used to retrieve similar [ImageContent] elements.
Expand All @@ -130,6 +108,27 @@ class AverageColor : Analyser<ImageContent, FloatVectorDescriptor> {
* @param content An array of [Content] elements to use with the [Retriever]
* @param context The [QueryContext] to use with the [Retriever]
*/
override fun newRetrieverForContent(field: Schema.Field<ImageContent, FloatVectorDescriptor>, content: Collection<ImageContent>, context: QueryContext): AverageColorRetriever =
this.newRetrieverForDescriptors(field, analyse(content), context)
override fun newRetrieverForContent(field: Schema.Field<ImageContent, FloatVectorDescriptor>, content: Collection<ImageContent>, context: QueryContext): DenseRetriever<ImageContent> =
this.newRetrieverForDescriptors(field, content.map { this.analyse(it) }, context)

/**
* Performs the [AverageColor] analysis on the provided [List] of [ImageContent] elements.
*
* @param content The [List] of [ImageContent] elements.
* @return [List] of [FloatVectorDescriptor]s.
*/
fun analyse(content: ImageContent): FloatVectorDescriptor {
val color = floatArrayOf(0f, 0f, 0f)
val rgb = content.content.getRGBArray()
for (c in rgb) {
val container = RGBColorContainer(c)
color[0] += container.red
color[1] += container.green
color[2] += container.blue
}

/* Generate descriptor. */
val averageColor = RGBColorContainer(color[0] / rgb.size, color[1] / rgb.size, color[2] / rgb.size)
return FloatVectorDescriptor(UUID.randomUUID(), null, averageColor.toVector())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ class AverageColorExtractor(input: Operator<Retrievable>, analyser: AverageColor
*/
override fun extract(retrievable: Retrievable): List<FloatVectorDescriptor> {
val content = retrievable.content.filterIsInstance<ImageContent>()
return AverageColor.analyse(content).map { it.copy(retrievableId = retrievable.id, field = this@AverageColorExtractor.field) }
return content.map { (this.analyser as AverageColor).analyse(it).copy(retrievableId = retrievable.id, field = this.field) }
}
}

This file was deleted.

Loading

0 comments on commit 02dfef1

Please sign in to comment.