Optimize Name hashCode
This commit is contained in:
parent
233639f0b6
commit
0cc4dc0db7
@ -9,6 +9,7 @@
|
||||
- More fine-grained types in Action builders.
|
||||
|
||||
### Changed
|
||||
- Meta `get` method allows nullable receiver
|
||||
- `withDefault` functions do not add new keys to meta children and are consistent.
|
||||
- `dataforge.meta.values` package is merged into `dataforge.meta` for better star imports
|
||||
- Kotlin 1.7.20
|
||||
|
@ -5,6 +5,7 @@ import kotlinx.serialization.json.Json
|
||||
import space.kscience.dataforge.misc.Type
|
||||
import space.kscience.dataforge.misc.unsafeCast
|
||||
import space.kscience.dataforge.names.*
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
|
||||
/**
|
||||
@ -94,6 +95,10 @@ public interface Meta : MetaRepr, MetaProvider {
|
||||
public val Meta.isLeaf: Boolean get() = items.isEmpty()
|
||||
|
||||
|
||||
public operator fun Meta?.get(token: NameToken): Meta? = this?.items?.get(token)
|
||||
|
||||
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
|
||||
@JvmName("getNonNullable")
|
||||
public operator fun Meta.get(token: NameToken): Meta? = items[token]
|
||||
|
||||
/**
|
||||
@ -103,11 +108,19 @@ public operator fun Meta.get(token: NameToken): Meta? = items[token]
|
||||
*/
|
||||
public operator fun Meta?.get(name: Name): Meta? = this?.getMeta(name)
|
||||
|
||||
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
|
||||
@JvmName("getNonNullable")
|
||||
public operator fun Meta.get(name: Name): Meta? = getMeta(name)
|
||||
|
||||
/**
|
||||
* Parse [Name] from [key] using full name notation and pass it to [Meta.get]
|
||||
*/
|
||||
public operator fun Meta?.get(key: String): Meta? = this?.get(key.parseAsName(true))
|
||||
|
||||
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
|
||||
@JvmName("getNonNullable")
|
||||
public operator fun Meta.get(key: String): Meta? = get(key.parseAsName(true))
|
||||
|
||||
/**
|
||||
* Get all items matching given name. The index of the last element, if present is used as a [Regex],
|
||||
* against which indexes of elements are matched.
|
||||
@ -162,7 +175,7 @@ public inline val <M : TypedMeta<M>> TypedMeta<M>.self: M get() = unsafeCast()
|
||||
|
||||
//public typealias Meta = TypedMeta<*>
|
||||
|
||||
public operator fun <M : TypedMeta<M>> TypedMeta<M>.get(token: NameToken): M? = items[token]
|
||||
public operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(token: NameToken): M? = this?.items?.get(token)
|
||||
|
||||
/**
|
||||
* Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [TypedMeta.items] of a parent node.
|
||||
@ -175,11 +188,19 @@ public tailrec operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(name: Name): M?
|
||||
else -> get(name.firstOrNull()!!)?.get(name.cutFirst())
|
||||
}
|
||||
|
||||
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
|
||||
@JvmName("getNonNullable")
|
||||
public operator fun <M : TypedMeta<M>> TypedMeta<M>.get(name: Name): M? = get(name)
|
||||
|
||||
/**
|
||||
* Parse [Name] from [key] using full name notation and pass it to [TypedMeta.get]
|
||||
*/
|
||||
public operator fun <M : TypedMeta<M>> TypedMeta<M>?.get(key: String): M? = this[key.parseAsName(true)]
|
||||
|
||||
@Deprecated("Use nullable receiver", level = DeprecationLevel.HIDDEN)
|
||||
@JvmName("getNonNullable")
|
||||
public operator fun <M : TypedMeta<M>> TypedMeta<M>.get(key: String): M? = get(key)
|
||||
|
||||
|
||||
/**
|
||||
* Get a sequence of [Name]-[Value] pairs using top-down traversal of the tree
|
||||
|
@ -24,13 +24,13 @@ public class Name(public val tokens: List<NameToken>) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return if (tokens.size == 1) {
|
||||
private val cachedHashCode = if (tokens.size == 1) {
|
||||
tokens.first().hashCode()
|
||||
} else {
|
||||
tokens.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = cachedHashCode
|
||||
|
||||
public companion object {
|
||||
public const val NAME_SEPARATOR: String = "."
|
||||
|
@ -9,7 +9,7 @@ import space.kscience.dataforge.misc.DFExperimental
|
||||
* A name token could have appendix in square brackets called *index*
|
||||
*/
|
||||
@Serializable(NameTokenSerializer::class)
|
||||
public data class NameToken(val body: String, val index: String? = null) {
|
||||
public class NameToken(public val body: String, public val index: String? = null) {
|
||||
|
||||
init {
|
||||
if (body.isEmpty()) error("Syntax error: Name token body is empty")
|
||||
@ -33,6 +33,7 @@ public data class NameToken(val body: String, val index: String? = null) {
|
||||
bodyEscaped
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return unescaped version of the [NameToken]. Should be used only for output because it is not possible to correctly
|
||||
* parse it back.
|
||||
@ -43,6 +44,22 @@ public data class NameToken(val body: String, val index: String? = null) {
|
||||
body
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || this::class != other::class) return false
|
||||
|
||||
other as NameToken
|
||||
|
||||
if (body != other.body) return false
|
||||
if (index != other.index) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private val cachedHashCode = body.hashCode() * 31 + (index?.hashCode() ?: 0)
|
||||
|
||||
override fun hashCode(): Int = cachedHashCode
|
||||
|
||||
public companion object {
|
||||
|
||||
private val escapedChars = listOf('\\', '.', '[', ']')
|
||||
|
@ -33,7 +33,7 @@ public fun Meta.toDynamic(): dynamic {
|
||||
public class DynamicMeta(internal val obj: dynamic) : TypedMeta<DynamicMeta> {
|
||||
private fun keys(): Array<String> = js("Object").keys(obj) as Array<String>
|
||||
|
||||
private fun isArray(@Suppress("UNUSED_PARAMETER") obj: dynamic): Boolean =
|
||||
private fun isArray(obj: dynamic): Boolean =
|
||||
js("Array").isArray(obj) as Boolean
|
||||
|
||||
private fun isPrimitive(obj: dynamic): Boolean =
|
||||
|
Loading…
Reference in New Issue
Block a user