dev.tauri.choam.internal.mcas.MemoryLocationOrdering.scala Maven / Gradle / Ivy
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2016-2024 Daniel Urban and contributors listed in NOTICE.txt
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.tauri.choam
package internal
package mcas
import scala.math.Ordering
private final class MemoryLocationOrdering[A]
extends Ordering[MemoryLocation[A]] {
final override def compare(x: MemoryLocation[A], y: MemoryLocation[A]): Int = {
this.globalCompare(x, y)
}
/**
* We don't really care HOW the `MemoryLocation`s are
* ordered; we just need a total global order. So we
* order them the way they're naturally in the `Hamt`.
*/
private[this] final def globalCompare(a: MemoryLocation[_], b: MemoryLocation[_]): Int = {
// We're essentially reimplementing here
// how `Hamt` compares hashes:
val W = 6
val ah = a.id
val bh = b.id
@tailrec
def go(shift: Int): Int = {
val r = Integer.compare(logicalIdx(ah, shift), logicalIdx(bh, shift))
if (r != 0) {
r
} else {
go(shift + W)
}
}
def logicalIdx(n: Long, shift: Int): Int = {
val mask = 0xFC00000000000000L >>> shift
val sh = java.lang.Long.numberOfTrailingZeros(mask)
((n & mask) >>> sh).toInt
}
if (a eq b) {
0
} else if (ah == bh) {
impossible(s"[globalCompare] ref collision: ${a} and ${b}")
} else {
go(0)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy