blob: f47459f6bd7980824a2b0b636999f6f26b160ed0 [file] [log] [blame]
/*
* 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.
*/
package org.apache.ignite.internal.util;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.BitSet;
import java.util.UUID;
import org.apache.ignite.lang.IgniteInternalException;
/**
* Implement hash calculator.
*/
public class HashCalculator {
private int hash = 0;
/**
* Append value to hash calculation.
*
* @param v Value to update hash.
*/
public void append(Object v) {
if (v == null) {
appendNull();
return;
}
if (v.getClass() == Byte.class) {
appendByte((byte) v);
} else if (v.getClass() == Short.class) {
appendShort((short) v);
} else if (v.getClass() == Integer.class) {
appendInt((int) v);
} else if (v.getClass() == Long.class) {
appendLong((long) v);
} else if (v.getClass() == Float.class) {
appendFloat((float) v);
} else if (v.getClass() == Double.class) {
appendDouble((Double) v);
} else if (v.getClass() == BigInteger.class) {
appendNumber((BigInteger) v);
} else if (v.getClass() == BigDecimal.class) {
appendDecimal((BigDecimal) v);
} else if (v.getClass() == UUID.class) {
appendUuid((UUID) v);
} else if (v.getClass() == LocalDate.class) {
appendDate((LocalDate) v);
} else if (v.getClass() == LocalTime.class) {
appendTime((LocalTime) v);
} else if (v.getClass() == LocalDateTime.class) {
appendDateTime((LocalDateTime) v);
} else if (v.getClass() == Instant.class) {
appendTimestamp((Instant) v);
} else if (v.getClass() == byte[].class) {
appendBytes((byte[]) v);
} else if (v.getClass() == String.class) {
appendString((String) v);
} else if (v.getClass() == BitSet.class) {
appendBitmask((BitSet) v);
} else {
throw new IgniteInternalException("Unsupported value type: [cls=" + v.getClass() + ']');
}
}
/**
* Append null value to hash calculation.
*/
public void appendNull() {
appendByte((byte) 0);
}
/**
* Append byte to hash calculation.
*
* @param v Value to update hash.
*/
public void appendByte(byte v) {
hash = HashUtils.hash32(v, hash);
}
/**
* Append short to hash calculation.
*
* @param v Value to update hash.
*/
public void appendShort(short v) {
hash = HashUtils.hash32(v, hash);
}
/**
* Append integer to hash calculation.
*
* @param v Value to update hash.
*/
public void appendInt(int v) {
hash = HashUtils.hash32(v, hash);
}
/**
* Append long to hash calculation.
*
* @param v Value to update hash.
*/
public void appendLong(long v) {
hash = HashUtils.hash32(v, hash);
}
/**
* Append float to hash calculation.
*
* @param v Value to update hash.
*/
public void appendFloat(float v) {
appendInt(Float.floatToRawIntBits(v));
}
/**
* Append double to hash calculation.
*
* @param v Value to update hash.
*/
public void appendDouble(double v) {
appendLong(Double.doubleToRawLongBits(v));
}
/**
* Append BigDecimal to hash calculation.
*
* @param v Value to update hash.
*/
public void appendDecimal(BigDecimal v) {
appendDouble(v.doubleValue());
}
/**
* Append BigInteger to hash calculation.
*
* @param v Value to update hash.
*/
public void appendNumber(BigInteger v) {
appendDouble(v.doubleValue());
}
/**
* Append UUID to hash calculation.
*
* @param v Value to update hash.
*/
public void appendUuid(UUID v) {
appendLong(v.getMostSignificantBits());
appendLong(v.getLeastSignificantBits());
}
/**
* Append string value to hash calculation.
*
* @param v Value to update hash.
*/
public void appendString(String v) {
appendBytes(v.getBytes(StandardCharsets.UTF_8));
}
/**
* Append byte array to hash calculation.
*
* @param v Value to update hash.
*/
public void appendBytes(byte[] v) {
hash = HashUtils.hash32(v, 0, v.length, hash);
}
/**
* Append BitSet to hash calculation.
*
* @param v Value to update hash.
*/
public void appendBitmask(BitSet v) {
appendBytes(v.toByteArray());
}
/**
* Append LocalDate to hash calculation.
*
* @param v Value to update hash.
*/
public void appendDate(LocalDate v) {
appendLong(v.getYear());
appendLong(v.getMonthValue());
appendLong(v.getDayOfMonth());
}
/**
* Append LocalTime to hash calculation.
*
* @param v Value to update hash.
*/
public void appendTime(LocalTime v) {
appendLong(v.getHour());
appendLong(v.getMinute());
appendLong(v.getSecond());
appendLong(v.getNano());
}
/**
* Append LocalDateTime to hash calculation.
*
* @param v Value to update hash.
*/
public void appendDateTime(LocalDateTime v) {
appendDate(v.toLocalDate());
appendTime(v.toLocalTime());
}
/**
* Append Instant to hash calculation.
*
* @param v Value to update hash.
*/
public void appendTimestamp(Instant v) {
appendLong(v.getEpochSecond());
appendLong(v.getNano());
}
/**
* Hash code calculated by previous appended values.
*
* @return Hash code calculated by appended values.
*/
public int hash() {
return hash;
}
/**
* Reset hash code calculation.
*/
public void reset() {
hash = 0;
}
}