Skip to content

Commit

Permalink
- some documentation
Browse files Browse the repository at this point in the history
- move globalIds from static to database property
- expose globalIds to remote api

relates to #21
  • Loading branch information
lehvolk committed Jul 20, 2022
1 parent 9162e1e commit f9b231b
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 127 deletions.
12 changes: 11 additions & 1 deletion core/src/main/kotlin/org/utbot/jcdb/api/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ enum class FieldUsageMode {
*/
interface CompilationDatabase : Closeable {

val globalIdStore: GlobalIdsStore

/**
* create classpath instance
*
Expand Down Expand Up @@ -361,4 +363,12 @@ interface CompilationDatabase : Closeable {
* await background jobs
*/
suspend fun awaitBackgroundJobs()
}
}

/**
* database store for storing indexes mappings between ids -> name
*/
interface GlobalIdsStore {
suspend fun getId(name: String): Int
suspend fun getName(id: Int): String?
}
10 changes: 5 additions & 5 deletions core/src/main/kotlin/org/utbot/jcdb/api/Index.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import java.io.OutputStream
*/
interface ByteCodeLocationIndexBuilder<T, INDEX: ByteCodeLocationIndex<T>> {

fun index(classNode: ClassNode)
suspend fun index(classNode: ClassNode)

fun index(classNode: ClassNode, methodNode: MethodNode)
suspend fun index(classNode: ClassNode, methodNode: MethodNode)

fun build(location: ByteCodeLocation): INDEX

Expand All @@ -22,17 +22,17 @@ interface ByteCodeLocationIndex<T> {

val location: ByteCodeLocation

fun query(term: String): Sequence<T>
suspend fun query(term: String): Sequence<T>
}

interface Feature<T, INDEX: ByteCodeLocationIndex<T>> {

val key: String

fun newBuilder() : ByteCodeLocationIndexBuilder<T, INDEX>
fun newBuilder(globalIdsStore: GlobalIdsStore) : ByteCodeLocationIndexBuilder<T, INDEX>

fun serialize(index: INDEX, out: OutputStream)

fun deserialize(location: ByteCodeLocation, stream: InputStream): INDEX?
fun deserialize(globalIdsStore: GlobalIdsStore, location: ByteCodeLocation, stream: InputStream): INDEX?

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import mu.KLogging
import org.utbot.jcdb.CompilationDatabaseSettings
import org.utbot.jcdb.api.*
import org.utbot.jcdb.impl.fs.*
import org.utbot.jcdb.impl.index.GlobalIds
import org.utbot.jcdb.impl.storage.PersistentEnvironment
import org.utbot.jcdb.impl.storage.scheme.LocationEntity
import org.utbot.jcdb.impl.tree.ClassTree
Expand All @@ -18,7 +19,8 @@ import java.util.concurrent.atomic.AtomicInteger

class CompilationDatabaseImpl(
private val persistentEnvironment: PersistentEnvironment? = null,
private val settings: CompilationDatabaseSettings
private val settings: CompilationDatabaseSettings,
override val globalIdStore: GlobalIds = GlobalIds()
) : CompilationDatabase {

companion object : KLogging()
Expand All @@ -27,7 +29,7 @@ class CompilationDatabaseImpl(
internal val javaRuntime = JavaRuntime(settings.jre)
private val hooks = settings.hooks.map { it(this) }

internal val featureRegistry = FeaturesRegistry(persistentEnvironment, settings.fullFeatures)
internal val featureRegistry = FeaturesRegistry(persistentEnvironment, globalIdStore, settings.fullFeatures)
internal val locationsRegistry = LocationsRegistry(featureRegistry)
private val backgroundJobs = ConcurrentHashMap<Int, Job>()

Expand Down Expand Up @@ -122,7 +124,7 @@ class CompilationDatabaseImpl(
}
}
}.joinAll()
persistentEnvironment?.globalIds?.sync()
persistentEnvironment?.globalIds?.sync(globalIdStore)
backgroundJobs.remove(backgroundJobId)
}
}
Expand Down Expand Up @@ -176,7 +178,7 @@ class CompilationDatabaseImpl(

internal suspend fun restoreDataFrom(locations: Map<LocationEntity, ByteCodeLocation>) {
val env = persistentEnvironment ?: return
env.globalIds.restore()
env.globalIds.restore(globalIdStore)
val trees = withContext(Dispatchers.IO) {
locations.map { (entity, location) ->
async {
Expand Down Expand Up @@ -206,7 +208,7 @@ class CompilationDatabaseImpl(
val data = entity.index(key)
if (data != null) {
val index = try {
deserialize(location, data)
deserialize(globalIdStore, location, data)
} catch (e: Exception) {
logger.warn(e) { "can't parse location" }
null
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/kotlin/org/utbot/jcdb/impl/FeaturesRegistry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.utbot.jcdb.impl
import org.utbot.jcdb.api.ByteCodeLocation
import org.utbot.jcdb.api.ByteCodeLocationIndex
import org.utbot.jcdb.api.Feature
import org.utbot.jcdb.api.GlobalIdsStore
import org.utbot.jcdb.impl.index.index
import org.utbot.jcdb.impl.storage.PersistentEnvironment
import org.utbot.jcdb.impl.tree.ClassNode
Expand All @@ -13,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap

class FeaturesRegistry(
private val persistence: PersistentEnvironment? = null,
val globalIdsStore: GlobalIdsStore,
val features: List<Feature<*, *>>
) : Closeable {
private val indexes: ConcurrentHashMap<ByteCodeLocation, ConcurrentHashMap<String, ByteCodeLocationIndex<*>>> = ConcurrentHashMap()
Expand All @@ -38,7 +40,7 @@ class FeaturesRegistry(
location: ByteCodeLocation,
classes: Collection<ClassNode>
) {
val builder = newBuilder()
val builder = newBuilder(globalIdsStore)
classes.forEach { node ->
index(node, builder)
}
Expand Down
45 changes: 24 additions & 21 deletions core/src/main/kotlin/org/utbot/jcdb/impl/index/HierarchyIndex.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import kotlinx.collections.immutable.toImmutableMap
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodNode
import org.utbot.jcdb.api.ByteCodeLocation
import org.utbot.jcdb.api.ByteCodeLocationIndex
import org.utbot.jcdb.api.ByteCodeLocationIndexBuilder
import org.utbot.jcdb.api.Feature
import org.utbot.jcdb.api.*
import java.io.InputStream
import java.io.OutputStream

class HierarchyIndexBuilder : ByteCodeLocationIndexBuilder<String, HierarchyIndex> {
class HierarchyIndexBuilder(private val globalIdsStore: GlobalIdsStore) :
ByteCodeLocationIndexBuilder<String, HierarchyIndex> {

// super class -> implementations
private val parentToSubClasses = hashMapOf<Int, HashSet<Int>>()

override fun index(classNode: ClassNode) {
override suspend fun index(classNode: ClassNode) {
val superClass = classNode.superName?.takeIf {
it != "java/lang/Object"
}
Expand All @@ -28,27 +26,27 @@ class HierarchyIndexBuilder : ByteCodeLocationIndexBuilder<String, HierarchyInde
}
}

override fun index(classNode: ClassNode, methodNode: MethodNode) {
override suspend fun index(classNode: ClassNode, methodNode: MethodNode) {
// nothing to do here
}

private fun addToIndex(parentInternalName: String, subClassInternalName: String) {
val parentName = parentInternalName.intId
val subClassName = subClassInternalName.intId
private suspend fun addToIndex(parentInternalName: String, subClassInternalName: String) {
val parentName = parentInternalName.intId()
val subClassName = subClassInternalName.intId()
val subClasses = parentToSubClasses.getOrPut(parentName) {
HashSet()
}
subClasses.add(subClassName)
}

private val String.intId: Int
get() {
val pureName = Type.getObjectType(this).className
return GlobalIds.getId(pureName)
}
private suspend fun String.intId(): Int {
val pureName = Type.getObjectType(this).className
return globalIdsStore.getId(pureName)
}

override fun build(location: ByteCodeLocation): HierarchyIndex {
return HierarchyIndex(
globalIdsStore = globalIdsStore,
location = location,
parentToSubClasses = parentToSubClasses.toImmutableMap()
)
Expand All @@ -58,14 +56,15 @@ class HierarchyIndexBuilder : ByteCodeLocationIndexBuilder<String, HierarchyInde


class HierarchyIndex(
private val globalIdsStore: GlobalIdsStore,
override val location: ByteCodeLocation,
internal val parentToSubClasses: Map<Int, Set<Int>>
) : ByteCodeLocationIndex<String> {

override fun query(term: String): Sequence<String> {
val parentClassId = GlobalIds.getId(term)
override suspend fun query(term: String): Sequence<String> {
val parentClassId = globalIdsStore.getId(term)
return parentToSubClasses[parentClassId]?.map {
GlobalIds.getName(it)
globalIdsStore.getName(it)
}?.asSequence()?.filterNotNull() ?: emptySequence()
}

Expand All @@ -75,9 +74,13 @@ object Hierarchy : Feature<String, HierarchyIndex> {

override val key = "hierarchy"

override fun newBuilder() = HierarchyIndexBuilder()
override fun newBuilder(globalIdsStore: GlobalIdsStore) = HierarchyIndexBuilder(globalIdsStore)

override fun deserialize(location: ByteCodeLocation, stream: InputStream): HierarchyIndex {
override fun deserialize(
globalIdsStore: GlobalIdsStore,
location: ByteCodeLocation,
stream: InputStream
): HierarchyIndex {
val reader = stream.reader()
val result = hashMapOf<Int, Set<Int>>()
reader.use {
Expand All @@ -86,7 +89,7 @@ object Hierarchy : Feature<String, HierarchyIndex> {
result[key] = value
}
}
return HierarchyIndex(location, result)
return HierarchyIndex(globalIdsStore, location, result)
}

override fun serialize(index: HierarchyIndex, out: OutputStream) {
Expand Down
7 changes: 4 additions & 3 deletions core/src/main/kotlin/org/utbot/jcdb/impl/index/Indexes.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.utbot.jcdb.impl.index

import org.utbot.jcdb.api.ByteCodeLocationIndexBuilder
import org.utbot.jcdb.api.GlobalIdsStore
import org.utbot.jcdb.impl.tree.ClassNode
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicInteger
Expand All @@ -14,7 +15,7 @@ suspend fun index(node: ClassNode, builder: ByteCodeLocationIndexBuilder<*, *>)
}


object GlobalIds {
class GlobalIds : GlobalIdsStore {

private val counter = AtomicInteger()

Expand All @@ -24,7 +25,7 @@ object GlobalIds {
@Volatile
private var locked = false

fun getId(name: String): Int {
override suspend fun getId(name: String): Int {
val id = all.getOrPut(name) {
if (locked) {
throw IllegalStateException("writing is locked")
Expand All @@ -35,7 +36,7 @@ object GlobalIds {
return id
}

fun getName(id: Int): String? {
override suspend fun getName(id: Int): String? {
return reversed.get(id)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,33 @@ import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.FieldInsnNode
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.MethodNode
import org.utbot.jcdb.api.ByteCodeLocation
import org.utbot.jcdb.api.ByteCodeLocationIndex
import org.utbot.jcdb.api.ByteCodeLocationIndexBuilder
import org.utbot.jcdb.api.Feature
import org.utbot.jcdb.api.*
import java.io.InputStream
import java.io.OutputStream


class ReversedUsageIndexBuilder : ByteCodeLocationIndexBuilder<String, ReversedUsageIndex> {
class ReversedUsageIndexBuilder(private val globalIdsStore: GlobalIdsStore) : ByteCodeLocationIndexBuilder<String, ReversedUsageIndex> {

// class method -> usages of methods|fields
private val fieldsUsages = hashMapOf<Int, HashSet<Int>>()
private val methodsUsages = hashMapOf<Int, HashSet<Int>>()

override fun index(classNode: ClassNode) {
override suspend fun index(classNode: ClassNode) {
}

override fun index(classNode: ClassNode, methodNode: MethodNode) {
override suspend fun index(classNode: ClassNode, methodNode: MethodNode) {
val pureName = Type.getObjectType(classNode.name).className
val id = GlobalIds.getId(pureName)
val id = globalIdsStore.getId(pureName)
methodNode.instructions.forEach {
when (it) {
is FieldInsnNode -> {
val owner = Type.getObjectType(it.owner).className
val key = GlobalIds.getId(owner + "#" + it.name)
val key = globalIdsStore.getId(owner + "#" + it.name)
fieldsUsages.getOrPut(key) { hashSetOf() }.add(id)
}
is MethodInsnNode -> {
val owner = Type.getObjectType(it.owner).className
val key = GlobalIds.getId(owner + "#" + it.name)
val key = globalIdsStore.getId(owner + "#" + it.name)
methodsUsages.getOrPut(key) { hashSetOf() }.add(id)
}
}
Expand All @@ -48,6 +45,7 @@ class ReversedUsageIndexBuilder : ByteCodeLocationIndexBuilder<String, ReversedU
override fun build(location: ByteCodeLocation): ReversedUsageIndex {
return ReversedUsageIndex(
location = location,
globalIdsStore = globalIdsStore,
fieldsUsages = fieldsUsages.toImmutableMap(),
methodsUsages = methodsUsages.toImmutableMap()
)
Expand All @@ -58,14 +56,15 @@ class ReversedUsageIndexBuilder : ByteCodeLocationIndexBuilder<String, ReversedU

class ReversedUsageIndex(
override val location: ByteCodeLocation,
internal val globalIdsStore: GlobalIdsStore,
internal val fieldsUsages: ImmutableMap<Int, Set<Int>>,
internal val methodsUsages: ImmutableMap<Int, Set<Int>>,
) : ByteCodeLocationIndex<String> {

override fun query(term: String): Sequence<String> {
val usages = fieldsUsages[GlobalIds.getId(term)].orEmpty() +
methodsUsages[GlobalIds.getId(term)].orEmpty()
return usages.map { GlobalIds.getName(it) }.asSequence().filterNotNull()
override suspend fun query(term: String): Sequence<String> {
val usages = fieldsUsages[globalIdsStore.getId(term)].orEmpty() +
methodsUsages[globalIdsStore.getId(term)].orEmpty()
return usages.map { globalIdsStore.getName(it) }.asSequence().filterNotNull()
}

}
Expand All @@ -75,9 +74,9 @@ object ReversedUsages : Feature<String, ReversedUsageIndex> {

override val key = "reversed-usages"

override fun newBuilder() = ReversedUsageIndexBuilder()
override fun newBuilder(globalIdsStore: GlobalIdsStore) = ReversedUsageIndexBuilder(globalIdsStore)

override fun deserialize(location: ByteCodeLocation, stream: InputStream): ReversedUsageIndex {
override fun deserialize(globalIdsStore: GlobalIdsStore, location: ByteCodeLocation, stream: InputStream): ReversedUsageIndex {
val reader = stream.reader()

val fields = hashMapOf<Int, Set<Int>>()
Expand All @@ -93,7 +92,7 @@ object ReversedUsages : Feature<String, ReversedUsageIndex> {
}
}
}
return ReversedUsageIndex(location, fields.toPersistentMap(), methods.toPersistentMap())
return ReversedUsageIndex(location, globalIdsStore, fields.toPersistentMap(), methods.toPersistentMap())

}

Expand Down
Loading

0 comments on commit f9b231b

Please sign in to comment.