Commit c1b0031e authored by ZWT's avatar ZWT

feat(吉林演示): 松原

1.修改风电站运行状态接口,增加模拟实际发电功率处理逻辑,完成接口冒烟测试;
2.修改天气数据处理定时任务,解决晚上十一点半天气预报数据处理异常问题,修改风资源预测数据和光伏资源预测数据时间处理逻辑,完成接口冒烟测试;
3.修改风机预测数据模块相关功能接口,增加判断当前部署环境逻辑,解决查询全量数据问题;
4.修改风机预测数据生成模块第三方风力发电数据生成功能,增加数据拆分逻辑,区分15分数据层级,完成功能冒烟测试;
5.修改风机预测监控页面历史风速统计接口,统计数据不显示问题及小数位过多问题;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent ec185e56
/* JUG Java Uuid Generator
*
* Copyright (c) 2002 Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* 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 com.fasterxml.uuid;
import java.io.Serializable;
import java.net.*;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.Random;
/**
* EthernetAddress encapsulates the 6-byte MAC address defined in
* IEEE 802.1 standard.
*/
public class EthernetAddress
implements Serializable, Cloneable, Comparable<EthernetAddress> {
private static final long serialVersionUID = 1L;
private final static char[] HEX_CHARS = "0123456789abcdefABCDEF".toCharArray();
/**
* We may need a random number generator, for creating dummy ethernet
* address if no real interface is found.
*/
protected static Random _rnd;
/**
* 48-bit MAC address, stored in 6 lowest-significant bytes (in
* big endian notation)
*/
protected final long _address;
/**
* Lazily-constructed String serialization
*/
private volatile String _asString;
/*
/**********************************************************************
/* Instance construction
/**********************************************************************
*/
/**
* String constructor; given a 'standard' ethernet MAC address string
* (like '00:C0:F0:3D:5B:7C'), constructs an EthernetAddress instance.
* <p>
* Note that string is case-insensitive, and also that leading zeroes
* may be omitted. Thus '00:C0:F0:3D:5B:7C' and '0:c0:f0:3d:5b:7c' are
* equivalent, and a 'null' address could be passed as ':::::' as well
* as '00:00:00:00:00:00' (or any other intermediate combination).
*
* @param addrStr String representation of the ethernet address
*/
public EthernetAddress(String addrStr)
throws NumberFormatException {
int len = addrStr.length();
long addr = 0L;
/* Ugh. Although the most logical format would be the 17-char one
* (12 hex digits separated by colons), apparently leading zeroes
* can be omitted. Thus... Can't just check string length. :-/
*/
for (int i = 0, j = 0; j < 6; ++j) {
if (i >= len) {
// Is valid if this would have been the last byte:
if (j == 5) {
addr <<= 8;
break;
}
throw new NumberFormatException("Incomplete ethernet address (missing one or more digits");
}
char c = addrStr.charAt(i);
++i;
int value;
// The whole number may be omitted (if it was zero):
if (c == ':') {
value = 0;
} else {
// No, got at least one digit?
if (c >= '0' && c <= '9') {
value = (c - '0');
} else if (c >= 'a' && c <= 'f') {
value = (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
value = (c - 'A' + 10);
} else {
throw new NumberFormatException("Non-hex character '" + c + "'");
}
// How about another one?
if (i < len) {
c = addrStr.charAt(i);
++i;
if (c != ':') {
value = (value << 4);
if (c >= '0' && c <= '9') {
value |= (c - '0');
} else if (c >= 'a' && c <= 'f') {
value |= (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
value |= (c - 'A' + 10);
} else {
throw new NumberFormatException("Non-hex character '" + c + "'");
}
}
}
}
addr = (addr << 8) | value;
if (c != ':') {
if (i < len) {
if (addrStr.charAt(i) != ':') {
throw new NumberFormatException("Expected ':', got ('" + addrStr.charAt(i) + "')");
}
++i;
} else if (j < 5) {
throw new NumberFormatException("Incomplete ethernet address (missing one or more digits");
}
}
}
_address = addr;
}
/**
* Binary constructor that constructs an instance given the 6 byte
* (48-bit) address. Useful if an address is saved in binary format
* (for saving space for example).
*/
public EthernetAddress(byte[] addr)
throws NumberFormatException {
if (addr.length != 6) {
throw new NumberFormatException("Ethernet address has to consist of 6 bytes");
}
long l = addr[0] & 0xFF;
for (int i = 1; i < 6; ++i) {
l = (l << 8) | (addr[i] & 0xFF);
}
_address = l;
}
/**
* Another binary constructor; constructs an instance from the given
* long argument; the lowest 6 bytes contain the address.
*
* @param addr long that contains the MAC address in 6 least significant
* bytes.
*/
public EthernetAddress(long addr) {
_address = addr;
}
/**
* Constructs a new EthernetAddress given the byte array that contains
* binary representation of the address.
* <p>
* Note that calling this method returns the same result as would
* using the matching constructor.
*
* @param addr Binary representation of the ethernet address
* @throws NumberFormatException if addr is invalid (less or more than
* 6 bytes in array)
*/
public static EthernetAddress valueOf(byte[] addr)
throws NumberFormatException {
return new EthernetAddress(addr);
}
/**
* Constructs a new EthernetAddress given the byte array that contains
* binary representation of the address.
* <p>
* Note that calling this method returns the same result as would
* using the matching constructor.
*
* @param addr Binary representation of the ethernet address
* @throws NumberFormatException if addr is invalid (less or more than
* 6 ints in array)
*/
public static EthernetAddress valueOf(int[] addr)
throws NumberFormatException {
byte[] bAddr = new byte[addr.length];
for (int i = 0; i < addr.length; ++i) {
bAddr[i] = (byte) addr[i];
}
return new EthernetAddress(bAddr);
}
/**
* Constructs a new EthernetAddress given a string representation of
* the ethernet address.
* <p>
* Note that calling this method returns the same result as would
* using the matching constructor.
*
* @param addrStr String representation of the ethernet address
* @throws NumberFormatException if addr representation is invalid
*/
public static EthernetAddress valueOf(String addrStr)
throws NumberFormatException {
return new EthernetAddress(addrStr);
}
/**
* Constructs a new EthernetAddress given the long int value (64-bit)
* representation of the ethernet address (of which 48 LSB contain
* the definition)
* <p>
* Note that calling this method returns the same result as would
* using the matching constructor.
*
* @param addr Long int representation of the ethernet address
*/
public static EthernetAddress valueOf(long addr) {
return new EthernetAddress(addr);
}
/**
* Factory method that locates a network interface that has
* a suitable mac address (ethernet cards, and things that
* emulate one), and return that address. If there are multiple
* applicable interfaces, one of them is returned; which one
* is returned is not specified.
* Method is meant for accessing an address needed to construct
* generator for time+location based UUID generation method.
*
* @return Ethernet address of one of interfaces system has;
* not including local or loopback addresses; if one exists,
* null if no such interfaces are found.
*/
public static EthernetAddress fromInterface() {
try {
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
while (en.hasMoreElements()) {
NetworkInterface nint = en.nextElement();
if (!nint.isLoopback()) {
EthernetAddress addr = fromInterface(nint);
if (addr != null) {
return addr;
}
}
}
} catch (java.net.SocketException e) {
// fine, let's take is as signal of not having any interfaces
}
return null;
}
/**
* A factory method to return the ethernet address of a specified network interface.
*
* @since 4.1
*/
public static EthernetAddress fromInterface(NetworkInterface nint) {
if (nint != null) {
try {
byte[] data = nint.getHardwareAddress();
if (data != null && data.length == 6) {
return new EthernetAddress(data);
}
} catch (SocketException e) {
// could not get address
}
}
return null;
}
/**
* A factory method that will try to determine the ethernet address of
* the network interface that connects to the default network gateway.
* To do this it will try to open a connection to one of the root DNS
* servers, or barring that, to address 1.1.1.1, or finally if that also
* fails then to IPv6 address "1::1". If a connection can be opened then
* the interface through which that connection is routed is determined
* to be the default egress interface, and the corresponding address of
* that interface will be returned. If all attempts are unsuccessful,
* null will be returned.
*
* @since 4.1
*/
public static EthernetAddress fromEgressInterface() {
String roots = "abcdefghijklm";
int index = new Random().nextInt(roots.length());
String name = roots.charAt(index) + ".root-servers.net";
InetSocketAddress externalAddress = new InetSocketAddress(name, 0);
if (externalAddress.isUnresolved()) {
externalAddress = new InetSocketAddress("1.1.1.1", 0);
}
EthernetAddress ifAddr = fromEgressInterface(externalAddress);
if (ifAddr == null) {
return fromEgressInterface(new InetSocketAddress("1::1", 0));
} else {
return ifAddr;
}
}
/**
* A factory method to return the address of the interface used to route
* traffic to the specified IP address.
*
* @since 4.1
*/
public static EthernetAddress fromEgressInterface(InetSocketAddress externalSocketAddress) {
try (DatagramSocket socket = new DatagramSocket()) {
socket.connect(externalSocketAddress);
InetAddress localAddress = socket.getLocalAddress();
NetworkInterface egressIf = NetworkInterface.getByInetAddress(localAddress);
return fromInterface(egressIf);
} catch (SocketException e) {
return null;
}
}
/**
* Factory method that can be used to construct a random multicast
* address; to be used in cases where there is no "real" ethernet
* address to use. Address to generate should be a multicast address
* to avoid accidental collision with real manufacturer-assigned
* MAC addresses.
* <p>
* Internally a {@link SecureRandom} instance is used for generating
* random number to base address on.
*/
public static EthernetAddress constructMulticastAddress() {
return constructMulticastAddress(_randomNumberGenerator());
}
/**
* Factory method that can be used to construct a random multicast
* address; to be used in cases where there is no "real" ethernet
* address to use. Address to generate should be a multicast address
* to avoid accidental collision with real manufacturer-assigned
* MAC addresses.
* <p>
* Address is created using specified random number generator.
*/
public static EthernetAddress constructMulticastAddress(Random rnd) {
byte[] dummy = new byte[6];
synchronized (rnd) {
rnd.nextBytes(dummy);
}
/* Need to set the broadcast bit to indicate it's not a real
* address.
*/
/* 20-May-2010, tatu: Actually, we could use both second least-sig-bit
* ("locally administered") or the LSB (multicast), as neither is
* ever set for 'real' addresses.
* Since UUID specs recommends latter, use that.
*/
dummy[0] |= (byte) 0x01;
return new EthernetAddress(dummy);
}
/**
* Helper method for accessing configured random number generator
*/
protected synchronized static Random _randomNumberGenerator() {
if (_rnd == null) {
_rnd = new SecureRandom();
}
return _rnd;
}
/*
/**********************************************************************
/* Conversions to raw types
/**********************************************************************
*/
/**
* Default cloning behaviour (bitwise copy) is just fine...
*/
@Override
public Object clone() {
return new EthernetAddress(_address);
}
/**
* Returns 6 byte byte array that contains the binary representation
* of this ethernet address; byte 0 is the most significant byte
* (and so forth)
*
* @return 6 byte byte array that contains the binary representation
*/
public byte[] asByteArray() {
byte[] result = new byte[6];
toByteArray(result);
return result;
}
/**
* Synonym to 'asByteArray()'
*
* @return 6 byte byte array that contains the binary representation
*/
public byte[] toByteArray() {
return asByteArray();
}
public void toByteArray(byte[] array) {
if (array.length < 6) {
throw new IllegalArgumentException("Too small array, need to have space for 6 bytes");
}
toByteArray(array, 0);
}
public void toByteArray(byte[] array, int pos) {
if (pos < 0 || (pos + 6) > array.length) {
throw new IllegalArgumentException("Illegal offset (" + pos + "), need room for 6 bytes");
}
int i = (int) (_address >> 32);
array[pos++] = (byte) (i >> 8);
array[pos++] = (byte) i;
i = (int) _address;
array[pos++] = (byte) (i >> 24);
array[pos++] = (byte) (i >> 16);
array[pos++] = (byte) (i >> 8);
array[pos] = (byte) i;
}
/*
/**********************************************************************
/* Accessors
/**********************************************************************
*/
public long toLong() {
return _address;
}
/**
* Method that can be used to check if this address refers
* to a multicast address.
* Such addresses are never assigned to individual network
* cards.
*/
public boolean isMulticastAddress() {
return (((int) (_address >> 40)) & 0x01) != 0;
}
/*
/**********************************************************************
/* Standard methods
/**********************************************************************
*/
/**
* Method that can be used to check if this address refers
* to a "locally administered address"
* (see [http://en.wikipedia.org/wiki/MAC_address] for details).
* Such addresses are not assigned to individual network
* cards.
*/
public boolean isLocallyAdministeredAddress() {
return (((int) (_address >> 40)) & 0x02) != 0;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
return ((EthernetAddress) o)._address == _address;
}
@Override
public int hashCode() {
return (int) _address ^ (int) (_address >>> 32);
}
/**
* Method that compares this EthernetAddress to one passed in as
* argument. Comparison is done simply by comparing individual
* address bytes in the order.
*
* @return negative number if this EthernetAddress should be sorted before the
* parameter address if they are equal, os positive non-zero number if this address
* should be sorted after parameter
*/
@Override
public int compareTo(EthernetAddress other) {
long l = _address - other._address;
if (l < 0L) return -1;
return (l == 0L) ? 0 : 1;
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
/**
* Returns the canonical string representation of this ethernet address.
* Canonical means that all characters are lower-case and string length
* is always 17 characters (ie. leading zeroes are not omitted).
*
* @return Canonical string representation of this ethernet address.
*/
@Override
public String toString() {
String str = _asString;
if (str != null) {
return str;
}
/* Let's not cache the output here (unlike with UUID), assuming
* this won't be called as often:
*/
StringBuilder b = new StringBuilder(17);
int i1 = (int) (_address >> 32);
int i2 = (int) _address;
_appendHex(b, i1 >> 8);
b.append(':');
_appendHex(b, i1);
b.append(':');
_appendHex(b, i2 >> 24);
b.append(':');
_appendHex(b, i2 >> 16);
b.append(':');
_appendHex(b, i2 >> 8);
b.append(':');
_appendHex(b, i2);
_asString = str = b.toString();
return str;
}
private final void _appendHex(StringBuilder sb, int hex) {
sb.append(HEX_CHARS[(hex >> 4) & 0xF]);
sb.append(HEX_CHARS[(hex & 0x0f)]);
}
}
\ No newline at end of file
package com.fasterxml.uuid;
import java.util.UUID;
/**
* Intermediate base class for UUID generators that do not take arguments for individual
* calls. This includes random and time-based variants, but not name-based ones.
*
* @since 3.0
*/
public abstract class NoArgGenerator extends UUIDGenerator {
public abstract UUID generate();
}
\ No newline at end of file
package com.fasterxml.uuid;
import java.util.UUID;
/**
* Intermediate base class for UUID generators that take one String argument for individual
* calls. This includes name-based generators, but not random and time-based generators.
*
* @since 3.0
*/
public abstract class StringArgGenerator extends UUIDGenerator {
/**
* Method for generating name-based UUIDs using specified name (serialized to
* bytes using UTF-8 encoding)
*/
public abstract UUID generate(String name);
/**
* Method for generating name-based UUIDs using specified byte-serialization
* of name.
*
* @since 3.1
*/
public abstract UUID generate(byte[] nameBytes);
}
\ No newline at end of file
/* JUG Java UUID Generator
*
* Copyright (c) 2002- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* 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 com.fasterxml.uuid;
/**
* Minimal "tag" base class from which all generator implementations
* derive. Actual generation methods are not included since different
* generators take different number of arguments.
*
* @since 3.0
*/
public abstract class UUIDGenerator {
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* Constructor is private to enforce singleton access.
*/
protected UUIDGenerator() {
}
/*
/**********************************************************
/* Shared (minimal) API
/**********************************************************
*/
/**
* Accessor for determining type of UUIDs (variant) that this
* generator instance will produce.
*/
public abstract UUIDType getType();
}
\ No newline at end of file
package com.fasterxml.uuid.impl;
import java.security.SecureRandom;
/**
* Trivial helper class that uses class loading as synchronization
* mechanism for lazy instantiation of the shared secure random
* instance.
*/
public final class LazyRandom {
private final static SecureRandom shared = new SecureRandom();
public static SecureRandom sharedSecureRandom() {
return shared;
}
}
\ No newline at end of file
package com.fasterxml.uuid.impl;
import com.fasterxml.uuid.StringArgGenerator;
import com.fasterxml.uuid.UUIDType;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.UUID;
/**
* Implementation of UUID generator that uses one of name-based generation methods
* (variants 3 (MD5) and 5 (SHA1)).
* <p>
* As all JUG provided implementations, this generator is fully thread-safe; access
* to digester is synchronized as necessary.
*
* @since 3.0
*/
public class NameBasedGenerator extends StringArgGenerator {
public final static Charset _utf8;
/**
* Namespace used when name is a DNS name.
*/
public final static UUID NAMESPACE_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
/**
* Namespace used when name is a URL.
*/
public final static UUID NAMESPACE_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
/**
* Namespace used when name is an OID.
*/
public final static UUID NAMESPACE_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
/**
* Namespace used when name is an X500 identifier
*/
public final static UUID NAMESPACE_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8");
static {
_utf8 = StandardCharsets.UTF_8;
}
/**
* Namespace to use as prefix.
*/
protected final UUID _namespace;
/*
/**********************************************************************
/* Configuration
/**********************************************************************
*/
/**
* Message digesster to use for hash calculation
*/
protected final MessageDigest _digester;
protected final UUIDType _type;
/*
/**********************************************************************
/* Construction
/**********************************************************************
*/
/**
* @param namespace of the namespace, as defined by the
* spec. UUID has 4 pre-defined "standard" name space strings
* that can be passed to UUID constructor (see example below).
* Note that this argument is optional; if no namespace is needed
* (for example when name includes namespace prefix), null may be passed.
* @param digester Hashing algorithm to use.
*/
public NameBasedGenerator(UUID namespace, MessageDigest digester, UUIDType type) {
_namespace = namespace;
// And default digester SHA-1
if (digester == null) {
throw new IllegalArgumentException("Digester not optional: cannot pass `null`");
}
if (type == null) {
String typeStr = digester.getAlgorithm();
if (typeStr.startsWith("MD5")) {
type = UUIDType.NAME_BASED_MD5;
} else if (typeStr.startsWith("SHA")) {
type = UUIDType.NAME_BASED_SHA1;
} else {
// Hmmh... error out? Let's default to SHA-1, but log a warning
type = UUIDType.NAME_BASED_SHA1;
LoggerFacade _logger = LoggerFacade.getLogger(getClass());
_logger.warn("Could not determine type of Digester from '%s'; assuming 'SHA-1' type", typeStr);
}
}
_digester = digester;
_type = type;
}
/*
/**********************************************************************
/* Access to config
/**********************************************************************
*/
@Override
public UUIDType getType() {
return _type;
}
public UUID getNamespace() {
return _namespace;
}
/*
/**********************************************************************
/* UUID generation
/**********************************************************************
*/
@Override
public UUID generate(String name) {
// !!! TODO: 14-Oct-2010, tatu: can repurpose faster UTF-8 encoding from Jackson
return generate(name.getBytes(_utf8));
}
@Override
public UUID generate(byte[] nameBytes) {
byte[] digest;
synchronized (_digester) {
_digester.reset();
if (_namespace != null) {
_digester.update(UUIDUtil.asByteArray(_namespace));
}
_digester.update(nameBytes);
digest = _digester.digest();
}
return UUIDUtil.constructUUID(_type, digest);
}
}
\ No newline at end of file
package com.fasterxml.uuid.impl;
import com.fasterxml.uuid.NoArgGenerator;
import com.fasterxml.uuid.UUIDType;
import java.security.SecureRandom;
import java.util.Random;
import java.util.UUID;
/**
* Implementation of UUID generator that uses generation method 4.
* <p>
* Note on random number generation when using {@link SecureRandom} for random number
* generation: the first time {@link SecureRandom} object is used, there is noticeable delay between
* calling the method and getting the reply. This is because SecureRandom
* has to initialize itself to reasonably random state. Thus, if you
* want to lessen delay, it may be be a good idea to either get the
* first random UUID asynchronously from a separate thread, or to
* use the other generateRandomBasedUUID passing a previously initialized
* SecureRandom instance.
*
* @since 3.0
*/
public class RandomBasedGenerator extends NoArgGenerator {
/**
* Random number generator that this generator uses.
*/
protected final Random _random;
/**
* Looks like {@link SecureRandom} implementation is more efficient
* using single call access (compared to basic {@link java.util.Random}),
* so let's use that knowledge to our benefit.
*/
protected final boolean _secureRandom;
/**
* @param rnd Random number generator to use for generating UUIDs; if null,
* shared default generator is used. Note that it is strongly recommend to
* use a <b>good</b> (pseudo) random number generator; for example, JDK's
* {@link SecureRandom}.
*/
public RandomBasedGenerator(Random rnd) {
if (rnd == null) {
rnd = LazyRandom.sharedSecureRandom();
_secureRandom = true;
} else {
_secureRandom = (rnd instanceof SecureRandom);
}
_random = rnd;
}
/*
/**********************************************************************
/* Access to config
/**********************************************************************
*/
protected static long _toLong(byte[] buffer, int offset) {
long l1 = _toInt(buffer, offset);
long l2 = _toInt(buffer, offset + 4);
return (l1 << 32) + ((l2 << 32) >>> 32);
}
/*
/**********************************************************************
/* UUID generation
/**********************************************************************
*/
private static long _toInt(byte[] buffer, int offset) {
return (buffer[offset] << 24)
+ ((buffer[++offset] & 0xFF) << 16)
+ ((buffer[++offset] & 0xFF) << 8)
+ (buffer[++offset] & 0xFF);
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
@Override
public UUIDType getType() {
return UUIDType.RANDOM_BASED;
}
@Override
public UUID generate() {
// 14-Oct-2010, tatu: Surprisingly, variant for reading byte array is
// tad faster for SecureRandom... so let's use that then
long r1, r2;
if (_secureRandom) {
final byte[] buffer = new byte[16];
_random.nextBytes(buffer);
r1 = _toLong(buffer, 0);
r2 = _toLong(buffer, 1);
} else {
r1 = _random.nextLong();
r2 = _random.nextLong();
}
return UUIDUtil.constructUUID(UUIDType.RANDOM_BASED, r1, r2);
}
}
\ No newline at end of file
package com.fasterxml.uuid.impl;
import com.fasterxml.uuid.NoArgGenerator;
import com.fasterxml.uuid.UUIDType;
import java.security.SecureRandom;
import java.util.Random;
import java.util.UUID;
/**
* Implementation of UUID generator that uses time/location based generation
* method field from the Unix Epoch timestamp source - the number of
* milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded
* <p>
* As all JUG provided implementations, this generator is fully thread-safe.
* Additionally it can also be made externally synchronized with other instances
* (even ones running on other JVMs); to do this, use
* {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer} (or
* equivalent).
*
* @since 4.1
*/
public class TimeBasedEpochGenerator extends NoArgGenerator {
/*
/**********************************************************************
/* Configuration
/**********************************************************************
*/
/**
* Random number generator that this generator uses.
*/
protected final Random _random;
/*
/**********************************************************************
/* Construction
/**********************************************************************
*/
/**
* @param rnd Random number generator to use for generating UUIDs; if null,
* shared default generator is used. Note that it is strongly recommend to
* use a <b>good</b> (pseudo) random number generator; for example, JDK's
* {@link SecureRandom}.
*/
public TimeBasedEpochGenerator(Random rnd) {
if (rnd == null) {
rnd = LazyRandom.sharedSecureRandom();
}
_random = rnd;
}
/*
/**********************************************************************
/* Access to config
/**********************************************************************
*/
protected static long _toLong(byte[] buffer) {
long l1 = _toInt(buffer, 0);
long l2 = _toInt(buffer, 4);
return (l1 << 32) + ((l2 << 32) >>> 32);
}
/*
/**********************************************************************
/* UUID generation
/**********************************************************************
*/
private static long _toInt(byte[] buffer, int offset) {
return (buffer[offset] << 24)
+ ((buffer[++offset] & 0xFF) << 16)
+ ((buffer[++offset] & 0xFF) << 8)
+ (buffer[++offset] & 0xFF);
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
private static long _toShort(byte[] buffer, int offset) {
return ((buffer[offset] & 0xFF) << 8)
+ (buffer[++offset] & 0xFF);
}
@Override
public UUIDType getType() {
return UUIDType.TIME_BASED_EPOCH;
}
@Override
public UUID generate() {
final long rawTimestamp = System.currentTimeMillis();
final byte[] rnd = new byte[10];
_random.nextBytes(rnd);
// Use only 48 lowest bits as per spec, next 16 bit from random
// (note: UUIDUtil.constuctUUID will add "version" so it's only 12
// actual random bits)
long l1 = (rawTimestamp << 16) | _toShort(rnd, 8);
// And then the other 64 bits of random; likewise UUIDUtil.constructUUID
// will overwrite first 2 random bits so it's "only" 62 bits
long l2 = _toLong(rnd);
// and as per above, this call fills in "variant" and "version" bits
return UUIDUtil.constructUUID(UUIDType.TIME_BASED_EPOCH, l1, l2);
}
}
package com.fasterxml.uuid.impl;
import com.fasterxml.uuid.EthernetAddress;
import com.fasterxml.uuid.NoArgGenerator;
import com.fasterxml.uuid.UUIDTimer;
import com.fasterxml.uuid.UUIDType;
import java.util.UUID;
/**
* Implementation of UUID generator that uses time/location based generation
* method (variant 1).
* <p>
* As all JUG provided implementations, this generator is fully thread-safe.
* Additionally it can also be made externally synchronized with other
* instances (even ones running on other JVMs); to do this,
* use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
* (or equivalent).
*
* @since 3.0
*/
public class TimeBasedGenerator extends NoArgGenerator {
/*
/**********************************************************************
/* Configuration
/**********************************************************************
*/
protected final EthernetAddress _ethernetAddress;
/**
* Object used for synchronizing access to timestamps, to guarantee
* that timestamps produced by this generator are unique and monotonically increasings.
* Some implementations offer even stronger guarantees, for example that
* same guarantee holds between instances running on different JVMs (or
* with native code).
*/
protected final UUIDTimer _timer;
/**
* Base values for the second long (last 8 bytes) of UUID to construct
*/
protected final long _uuidL2;
/*
/**********************************************************************
/* Construction
/**********************************************************************
*/
/**
* @param ethAddr Hardware address (802.1) to use for generating
* spatially unique part of UUID. If system has more than one NIC,
*/
public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer) {
byte[] uuidBytes = new byte[16];
if (ethAddr == null) {
ethAddr = EthernetAddress.constructMulticastAddress();
}
// initialize baseline with MAC address info
_ethernetAddress = ethAddr;
_ethernetAddress.toByteArray(uuidBytes, 10);
// and add clock sequence
int clockSeq = timer.getClockSequence();
uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE + 1] = (byte) clockSeq;
long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
_uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
_timer = timer;
}
/*
/**********************************************************************
/* Access to config
/**********************************************************************
*/
@Override
public UUIDType getType() {
return UUIDType.TIME_BASED;
}
public EthernetAddress getEthernetAddress() {
return _ethernetAddress;
}
/*
/**********************************************************************
/* UUID generation
/**********************************************************************
*/
/* As timer is not synchronized (nor _uuidBytes), need to sync; but most
* importantly, synchronize on timer which may also be shared between
* multiple instances
*/
@Override
public UUID generate() {
final long rawTimestamp = _timer.getTimestamp();
// Time field components are kind of shuffled, need to slice:
int clockHi = (int) (rawTimestamp >>> 32);
int clockLo = (int) rawTimestamp;
// and dice
int midhi = (clockHi << 16) | (clockHi >>> 16);
// need to squeeze in type (4 MSBs in byte 6, clock hi)
midhi &= ~0xF000; // remove high nibble of 6th byte
midhi |= 0x1000; // type 1
long midhiL = midhi;
midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
// and reconstruct
long l1 = (((long) clockLo) << 32) | midhiL;
// last detail: must force 2 MSB to be '10'
return new UUID(l1, _uuidL2);
}
}
\ No newline at end of file
package com.fasterxml.uuid.impl;
import com.fasterxml.uuid.EthernetAddress;
import com.fasterxml.uuid.NoArgGenerator;
import com.fasterxml.uuid.UUIDTimer;
import com.fasterxml.uuid.UUIDType;
import java.util.UUID;
/**
* Implementation of UUID generator that uses time/location based generation
* method field compatible with UUIDv1, reorderd for improved DB locality
* (variant 6).
* <p>
* As all JUG provided implementations, this generator is fully thread-safe.
* Additionally it can also be made externally synchronized with other instances
* (even ones running on other JVMs); to do this, use
* {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer} (or
* equivalent).
*
* @since 4.1
*/
public class TimeBasedReorderedGenerator extends NoArgGenerator {
public static int BYTE_OFFSET_TIME_HIGH = 0;
public static int BYTE_OFFSET_TIME_MID = 4;
public static int BYTE_OFFSET_TIME_LOW = 7;
/*
/**********************************************************************
/* Configuration
/**********************************************************************
*/
protected final EthernetAddress _ethernetAddress;
/**
* Object used for synchronizing access to timestamps, to guarantee
* that timestamps produced by this generator are unique and monotonically increasings.
* Some implementations offer even stronger guarantees, for example that
* same guarantee holds between instances running on different JVMs (or
* with native code).
*/
protected final UUIDTimer _timer;
/**
* Base values for the second long (last 8 bytes) of UUID to construct
*/
protected final long _uuidL2;
/*
/**********************************************************************
/* Construction
/**********************************************************************
*/
/**
* @param ethAddr Hardware address (802.1) to use for generating
* spatially unique part of UUID. If system has more than one NIC,
*/
public TimeBasedReorderedGenerator(EthernetAddress ethAddr, UUIDTimer timer) {
byte[] uuidBytes = new byte[16];
if (ethAddr == null) {
ethAddr = EthernetAddress.constructMulticastAddress();
}
// initialize baseline with MAC address info
_ethernetAddress = ethAddr;
_ethernetAddress.toByteArray(uuidBytes, 10);
// and add clock sequence
int clockSeq = timer.getClockSequence();
uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE + 1] = (byte) clockSeq;
long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
_uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
_timer = timer;
}
/*
/**********************************************************************
/* Access to config
/**********************************************************************
*/
@Override
public UUIDType getType() {
return UUIDType.TIME_BASED_REORDERED;
}
public EthernetAddress getEthernetAddress() {
return _ethernetAddress;
}
/*
/**********************************************************************
/* UUID generation
/**********************************************************************
*/
/* As timer is not synchronized (nor _uuidBytes), need to sync; but most
* importantly, synchronize on timer which may also be shared between
* multiple instances
*/
@Override
public UUID generate() {
// Ok, get 60-bit timestamp (4 MSB are ignored)
final long rawTimestamp = _timer.getTimestamp();
// First: discard 4 MSB, next 32 bits (top of 60-bit timestamp) form the
// highest 32-bit segments
final long timestampHigh = (rawTimestamp >>> 28) << 32;
// and then bottom 28 bits split into mid (16 bits), low (12 bits)
final int timestampLow = (int) rawTimestamp;
// and then low part gets mixed with variant identifier
long timeBottomL = ((long) ((timestampLow >> 12) & 0xFFFF) << 16)
// and final 12 bits mixed with variant identifier
| 0x6000 | (timestampLow & 0xFFF);
timeBottomL = ((timeBottomL << 32) >>> 32); // to get rid of sign extension
// and reconstruct
long l1 = timestampHigh | timeBottomL;
return new UUID(l1, _uuidL2);
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment