All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jetbrains.exodus.entitystore.EventsMultiplexerInternal.kt Maven / Gradle / Ivy

package jetbrains.exodus.entitystore

import jetbrains.exodus.core.execution.Job
import jetbrains.exodus.database.EntityChangeType.*
import jetbrains.exodus.database.IEntityListener
import jetbrains.exodus.database.TransientChangesTracker
import jetbrains.exodus.database.TransientEntityChange
import jetbrains.exodus.database.TransientEntityStore
import jetbrains.exodus.entitystore.Where.*
import java.util.*

internal fun handleChange(
        where: Where,
        c: TransientEntityChange,
        listeners: Queue>
) = when (where) {
    SYNC_BEFORE_FLUSH_BEFORE_CONSTRAINTS -> when (c.changeType) {
        ADD -> listeners.visit(true) { it.addedSyncBeforeConstraints(c.transientEntity) }
        UPDATE -> listeners.visit(true) { it.updatedSyncBeforeConstraints(c.snaphotEntity, c.transientEntity) }
        REMOVE -> listeners.visit(true) { it.removedSyncBeforeConstraints(c.snaphotEntity) }
    }
    SYNC_BEFORE_FLUSH_AFTER_CONSTRAINTS -> when (c.changeType) {
        ADD -> listeners.visit { it.addedSyncAfterConstraints(c.transientEntity) }
        UPDATE -> listeners.visit { it.updatedSyncAfterConstraints(c.snaphotEntity, c.transientEntity) }
        REMOVE -> listeners.visit { it.removedSyncAfterConstraints(c.snaphotEntity) }
    }
    SYNC_AFTER_FLUSH -> when (c.changeType) {
        ADD -> listeners.visit { it.addedSync(c.transientEntity) }
        UPDATE -> listeners.visit { it.updatedSync(c.snaphotEntity, c.transientEntity) }
        REMOVE -> listeners.visit { it.removedSync(c.snaphotEntity) }
    }
    ASYNC_AFTER_FLUSH -> when (c.changeType) {
        ADD -> listeners.visit { it.addedAsync(c.transientEntity) }
        UPDATE -> listeners.visit { it.updatedAsync(c.snaphotEntity, c.transientEntity) }
        REMOVE -> listeners.visit { it.removedAsync(c.snaphotEntity) }
    }
}

private fun Queue>.visit(rethrow: Boolean = false, action: (IEntityListener) -> Unit) {
    for (l in this) {
        try {
            action(l)
        } catch (e: Exception) {
            // rethrow exception only for beforeFlush listeners
            if (rethrow) {
                if (e is RuntimeException) {
                    throw e
                }
                throw RuntimeException(e)
            } else {
                if (EventsMultiplexer.logger.isErrorEnabled) {
                    EventsMultiplexer.logger.error("Exception while notifying entity listener.", e)
                }
            }
        }
    }
}

internal class FullEntityId(store: EntityStore, id: EntityId) {
    private val storeHashCode: Int = System.identityHashCode(store)
    private val entityTypeId: Int = id.typeId
    private val entityLocalId: Long = id.localId

    override fun equals(other: Any?): Boolean {
        if (this === other) {
            return true
        }
        if (other !is FullEntityId) {
            return false
        }
        if (storeHashCode != other.storeHashCode) {
            return false
        }
        return if (entityLocalId != other.entityLocalId) {
            false
        } else entityTypeId == other.entityTypeId
    }

    override fun hashCode(): Int {
        var result = storeHashCode
        result = 31 * result + entityTypeId
        result = 31 * result + (entityLocalId xor (entityLocalId shr 32)).toInt()
        return result
    }

    override fun toString(): String {
        val builder = StringBuilder(10)
        toString(builder)
        return builder.toString()
    }

    fun toString(builder: StringBuilder) {
        builder.append(entityTypeId)
        builder.append('-')
        builder.append(entityLocalId)
        builder.append('@')
        builder.append(storeHashCode)
    }
}

internal class EventsMultiplexerJob(
        private val store: TransientEntityStore,
        private val eventsMultiplexer: EventsMultiplexer,
        private val changes: Set,
        private val changesTracker: TransientChangesTracker
) : Job() {

    @Throws(Throwable::class)
    public override fun execute() {
        try {
            store.run(Runnable {
                eventsMultiplexer.fire(store, Where.ASYNC_AFTER_FLUSH, [email protected])
            })
        } finally {
            changesTracker.dispose()
        }
    }

    override fun getName() = "Async events from EventMultiplexer"

    override fun getGroup(): String {
        return changesTracker.snapshot.getStore().location
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy