001
014
015 package com.liferay.counter.service.persistence.impl;
016
017 import com.liferay.portal.kernel.io.BigEndianCodec;
018
019
023 public class MultiDataCenterCounterFinderImpl extends CounterFinderImpl {
024
025 public MultiDataCenterCounterFinderImpl(
026 int dataCenterCount, int dataCenterDeploymentId) {
027
028 _multiDataCenterBits = getBits(dataCenterCount - 1);
029
030 if (_multiDataCenterBits > _BYTE_SHIFTS_MAX) {
031 throw new IllegalArgumentException(
032 "Unable to shift more than 8 bits");
033 }
034
035 if (getBits(dataCenterDeploymentId) > _multiDataCenterBits) {
036 throw new IllegalArgumentException(
037 "Invalid data center count " + dataCenterCount +
038 " or data center deployment ID " + dataCenterDeploymentId);
039 }
040
041 int bits = (_BYTE_SHIFTS_MAX - _multiDataCenterBits);
042
043 _mostSignificantByte = (byte)(dataCenterDeploymentId << bits);
044 }
045
046 @Override
047 public long increment(String name, int size) {
048 return getMultiClusterSafeValue(super.increment(name, size));
049 }
050
051 protected static int getBits(int value) {
052 if (value == 0) {
053 return 0;
054 }
055
056 return 32 - Integer.numberOfLeadingZeros(value);
057 }
058
059 protected long getMultiClusterSafeValue(long value) {
060 byte[] bytes = new byte[8];
061
062 BigEndianCodec.putLong(bytes, 0, value);
063
064 int modifiedLeftMostByte = (bytes[0] >>> _multiDataCenterBits);
065
066 bytes[0] = (byte)(modifiedLeftMostByte + _mostSignificantByte);
067
068 return BigEndianCodec.getLong(bytes, 0);
069 }
070
071 private static final int _BYTE_SHIFTS_MAX = 7;
072
073 private final byte _mostSignificantByte;
074 private final int _multiDataCenterBits;
075
076 }