io.altoo.serialization.kryo.scala.serializer.KryoClassResolver.scala Maven / Gradle / Ivy
/**
* *****************************************************************************
* Copyright 2012 Roman Levenstein
*
* 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 io.altoo.serialization.kryo.scala.serializer
import com.esotericsoftware.kryo.kryo5.Registration
import com.esotericsoftware.kryo.kryo5.util.DefaultClassResolver
class KryoClassResolver(val logImplicits: Boolean) extends DefaultClassResolver {
override def registerImplicit(typ: Class[?]): Registration = {
if (kryo.isRegistrationRequired) {
throw new IllegalArgumentException("Class is not registered: " + typ.getName
+ "\nNote: To register this class use: kryo.register(" + typ.getName + ".class);")
}
// registerInternal(new Registration(typ, kryo.getDefaultSerializer(typ), DefaultClassResolver.NAME))
/* TODO: This does not work if sender and receiver are
* initialized independently and using different order of classes
* Try to ensure that the same ID is assigned to the same classname
* by every Kryo instance:
*/
// Take a next available ID
// register(typ, kryo.getDefaultSerializer(typ))
// Use typename hashCode as an ID. It is pretty unique and is independent of the order of class registration
// and node that performs it. The disadvantage is: it takes more bytes to encode and it is still dependent
// on the order in which messages arrive on the deserializer side, because only the first message will contain
// the ID->FQCN mapping.
// val implicitRegistration = kryo.register(new Registration(typ, kryo.getDefaultSerializer(typ), typ.getName.hashCode()>>>1))
val implicitRegistration = kryo.register(new Registration(typ, kryo.getDefaultSerializer(typ), MurmurHash.hash(typ.getName.getBytes("UTF-8"), 0) >>> 1))
if (logImplicits) {
val registration = kryo.getRegistration(typ)
if (registration.getId == DefaultClassResolver.NAME)
println("Implicitly registered class " + typ.getName)
else
println("Implicitly registered class with id: " + typ.getName + "=" + registration.getId)
}
implicitRegistration
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* This is a very fast, non-cryptographic hash suitable for general hash-based
* lookup. See http://murmurhash.googlepages.com/ for more details.
*
* The C version of MurmurHash 2.0 found at that site was ported
* to Java by Andrzej Bialecki (ab at getopt org).
*/
object MurmurHash {
def hash(data: Array[Byte], seed: Int): Int = {
val m: Int = 0x5BD1E995
val r: Int = 24
var h: Int = seed ^ data.length
val len = data.length
val len_4 = len >> 2
var i = 0
while (i < len_4) {
val i_4 = i << 2
var k: Int = data(i_4 + 3)
k = k << 8
k = k | (data(i_4 + 2) & 0xFF)
k = k << 8
k = k | (data(i_4 + 1) & 0xFF)
k = k << 8
k = k | (data(i_4 + 0) & 0xFF)
k *= m
k ^= k >>> r
k *= m
h *= m
h ^= k
i = i + 1
}
val len_m = len_4 << 2
val left = len - len_m
if (left != 0) {
if (left >= 3) {
h ^= (data(len - 3): Int) << 16
}
if (left >= 2) {
h ^= (data(len - 2): Int) << 8
}
if (left >= 1) {
h ^= (data(len - 1): Int)
}
h *= m
}
h ^= h >>> 13
h *= m
h ^= h >>> 15
h
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy