Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
# Conflicts:
#	config.json
  • Loading branch information
ppanopticon committed Jan 15, 2024
2 parents 01af8ba + c6bde69 commit bce794b
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 38 deletions.
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schemas": [
{
"name": "v3c",
"name": "V3C",
"connection": {
"database": "CottontailConnectionProvider",
"parameters": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ object IndexContextFactory {
val resolverFactory = loadServiceForName<ResolverFactory>(contextConfig.resolverFactory) ?: throw IllegalArgumentException("Failed to find resolver implementation for name '${contextConfig.resolverFactory}'.")

/* Return new context. */
return IndexContext(schema, contentFactory, resolverFactory.newResolver(contextConfig.parameters))
return IndexContext(schema, contentFactory, resolverFactory.newResolver(schema, contextConfig.parameters))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class SchemaManager {
it.name,
loadServiceForName<ExporterFactory>(it.factory) ?: throw IllegalArgumentException("Failed to find exporter factory implementation for '${it.factory}'."),
it.parameters,
(loadServiceForName<ResolverFactory>(it.resolver.factory) ?: throw IllegalArgumentException("Failed to find resolver factory implementation for '${it.resolver.factory}'.")).newResolver(it.resolver.parameters),
(loadServiceForName<ResolverFactory>(it.resolver.factory) ?: throw IllegalArgumentException("Failed to find resolver factory implementation for '${it.resolver.factory}'.")).newResolver(schema, it.resolver.parameters),
)
}
config.extractionPipelines.map {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package org.vitrivr.engine.core.resolver

import org.vitrivr.engine.core.model.metamodel.Schema

/**
* A factory class for [Resolver]s.
*
* @author Fynn Faber
* @version 1.0.0.
*/
interface ResolverFactory {

/**
* Generates a new [Resolver] instance using the provided [parameters].
*
* @param schema The [Schema] on which the [Resolver] operates
* @param parameters The parameters used to configure [Resolver]
* @return [Resolver]
*/
fun newResolver(parameters: Map<String, Any>): Resolver
fun newResolver(schema: Schema, parameters: Map<String, String>): Resolver
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.vitrivr.engine.index.resolvers

import org.vitrivr.engine.core.model.metamodel.Schema
import org.vitrivr.engine.core.model.retrievable.RetrievableId
import org.vitrivr.engine.core.resolver.Resolvable
import org.vitrivr.engine.core.resolver.Resolver
Expand All @@ -25,9 +26,9 @@ class DiskResolver : ResolverFactory {
* @param parameters The parameters used to configure [Resolver]
* @return [DiskResolver]
*/
override fun newResolver(parameters: Map<String, Any>): Resolver {
val location = Paths.get(parameters["location"] as? String ?: "./thumbnails")
val mimeType = MimeType.valueOf(parameters["mimeType"] as? String ?: "JPG")
override fun newResolver(schema: Schema, parameters: Map<String, String>): Resolver {
val location = Paths.get(parameters["location"] ?: "./thumbnails/${schema.name}")
val mimeType = MimeType.valueOf(parameters["mimeType"] ?: "JPG")
return Instance(location, mimeType)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class TemporalSequenceAggregator(
emit(it)
}

//at least 2 inputs are required for a sequence
if (inputs.size < 2 || inputs.filter { it.isNotEmpty() }.size < 2) {
return@flow
}

//start with temporal aggregation

val continuousSequences = mutableMapOf<RetrievableId, MutableList<ContinuousSequence>>()
Expand All @@ -54,10 +59,11 @@ class TemporalSequenceAggregator(
}

//get all valid segments per source, sorted by time if available
val segments = source.relationships.asSequence().filter { it.pred == "partOf" && it.obj.first == source.id }
.mapNotNull { retrievedMap[it.sub.first] }.filterIsInstance<Retrieved.RetrievedWithProperties>()
.filter { it.properties["start"]?.toLongOrNull() != null && it.properties["end"]?.toLongOrNull() != null }
.sortedBy { it.properties["start"]!!.toLong() }.toList()
val segments =
source.relationships.asSequence().filter { it.pred == "partOf" && it.obj.first == source.id }
.mapNotNull { retrievedMap[it.sub.first] }.filterIsInstance<Retrieved.RetrievedWithProperties>()
.filter { it.properties["start"]?.toLongOrNull() != null && it.properties["end"]?.toLongOrNull() != null }
.sortedBy { it.properties["start"]!!.toLong() }.toList()

if (segments.isEmpty()) {
continue
Expand Down Expand Up @@ -122,6 +128,11 @@ class TemporalSequenceAggregator(

val stages = sequences.groupBy { it.stage }

//skip sequences that have only results for one 'stage'
if (stages.size < 2) {
continue
}

//sequentially go over all stage indices to try and start sequences
for (startStageId in inputs.indices) {

Expand All @@ -133,9 +144,12 @@ class TemporalSequenceAggregator(
for (nextStageId in ((startStageId + 1) until inputs.size)) {

val maxStartTime = temporalSequence.last().end + MAX_TIME_BETWEEN_STAGES
stages[nextStageId]?.filter { it.start <= maxStartTime }?.maxBy { it.score }?.let {
temporalSequence.add(it) //add highest scored sequence within range
}
val minStartTime = temporalSequence.last().start

stages[nextStageId]?.filter { it.start in minStartTime..maxStartTime }?.maxByOrNull { it.score }
?.let {
temporalSequence.add(it) //add highest scored sequence within range
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.vitrivr.engine.query.aggregate

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList
import org.vitrivr.engine.core.model.retrievable.Retrievable
Expand All @@ -26,44 +27,61 @@ class WeightedScoreFusion(

private val weightsSum = this.weights.sum()

override fun toFlow(scope: CoroutineScope): Flow<Retrieved> = flow {
override fun toFlow(scope: CoroutineScope): Flow<Retrieved> {

val inputs = inputs.map { it.toFlow(scope).toList() }
if (inputs.isEmpty()) {
return emptyFlow()
}

val scoreMap = mutableMapOf<RetrievableId, MutableList<Pair<Int, Retrievable>>>()
if (inputs.size == 1) {
return inputs.first().toFlow(scope)
}

for ((index, retrieveds) in inputs.withIndex()) {
return flow {

for (retrieved in retrieveds) {
val inputs = inputs.map { it.toFlow(scope).toList() }

if (!scoreMap.containsKey(retrieved.id)) {
scoreMap[retrieved.id] = mutableListOf()
}
//check if there is more than one populated input, return early if not
if (inputs.filter { it.isNotEmpty() }.size < 2) {
inputs.asSequence().flatten().forEach { emit(it) }
return@flow
}

val scoreMap = mutableMapOf<RetrievableId, MutableList<Pair<Int, Retrievable>>>()

for ((index, retrieveds) in inputs.withIndex()) {

for (retrieved in retrieveds) {

scoreMap[retrieved.id]!!.add(index to retrieved)
if (!scoreMap.containsKey(retrieved.id)) {
scoreMap[retrieved.id] = mutableListOf()
}

scoreMap[retrieved.id]!!.add(index to retrieved)

}

}

}
for((_, retrieveds) in scoreMap) {

for((_, retrieveds) in scoreMap) {
val score = retrieveds.map { ((it.second as? Retrieved.RetrievedWithScore)?.score ?: 0f) * weights[it.first] }.sum() / weightsSum

val score = retrieveds.map { ((it.second as? Retrieved.RetrievedWithScore)?.score ?: 0f) * weights[it.first] }.sum() / weightsSum
val first = retrieveds.first().second

val first = retrieveds.first().second

//TODO better merging with type/attribute preservation
val retrieved = Retrieved.WithScore(
first.id,
first.type,
score,
false
)

//TODO better merging with type/attribute preservation
val retrieved = Retrieved.WithScore(
first.id,
first.type,
score,
false
)
emit(retrieved)

emit(retrieved)
}

}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object KotlinxJsonMapper : JsonMapper {
null
} catch (e: IllegalStateException) {
null
} ?: fallbackMapper.readValue(json, object : TypeReference<T>() {})
} ?: fallbackMapper.readValue(json, fallbackMapper.typeFactory.constructType(targetType))

}

Expand Down

0 comments on commit bce794b

Please sign in to comment.