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

org.alephium.protocol.model.CliqueId.scala Maven / Gradle / Ivy

There is a newer version: 3.8.8
Show newest version
// Copyright 2018 The Alephium Authors
// This file is part of the alephium project.
//
// The library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the library. If not, see .

package org.alephium.protocol.model

import akka.util.ByteString

import org.alephium.macros.HPC.cfor
import org.alephium.protocol.PublicKey
import org.alephium.serde.RandomBytes
import org.alephium.util.Bytes.byteStringOrdering

/** 160bits identifier of a Peer * */
class CliqueId(val publicKey: PublicKey) extends RandomBytes with Ordered[CliqueId] {
  def length: Int       = CliqueId.length
  val bytes: ByteString = publicKey.bytes
  def hammingDist(another: CliqueId): Int = {
    CliqueId.hammingDist(this, another)
  }

  override def compare(that: CliqueId): Int = byteStringOrdering.compare(this.bytes, that.bytes)
}

object CliqueId
    extends RandomBytes.Companion[CliqueId](
      bs => {
        assume(bs.size == cliqueIdLength)
        new CliqueId(PublicKey.unsafe(bs))
      },
      _.bytes
    ) {
  override def length: Int = cliqueIdLength

  def apply(publicKey: PublicKey): CliqueId = new CliqueId(publicKey)

  @SuppressWarnings(Array("org.wartremover.warts.While"))
  def hammingDist(cliqueId0: CliqueId, cliqueId1: CliqueId): Int = {
    val bytes0 = cliqueId0.bytes
    val bytes1 = cliqueId1.bytes
    var dist   = 0
    cfor(0)(_ < length, _ + 1) { i => dist += hammingDist(bytes0(i), bytes1(i)) }
    dist
  }

  def hammingOrder(target: CliqueId): Ordering[CliqueId] = Ordering.by(hammingDist(target, _))

  private val countLookUp = Array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4)

  def hammingDist(byte0: Byte, byte1: Byte): Int = {
    val xor = byte0 ^ byte1
    countLookUp(xor & 0x0f) + countLookUp((xor >> 4) & 0x0f)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy