Added MersenneTwisterFast (replaces java.util.Random), added missing licenses. Added field annonation exclusion serilaizer. Code polish
This commit is contained in:
parent
499e0bbfd7
commit
61e9862069
|
@ -4,36 +4,36 @@ Legal:
|
||||||
|
|
||||||
- Copyright (c) 2010 and beyond, dorkbox llc. All rights reserved.
|
- Copyright (c) 2010 and beyond, dorkbox llc. All rights reserved.
|
||||||
|
|
||||||
This software is a commercial product. Use, redistribution, and
|
This software is a commercial product. Use, redistribution, and
|
||||||
modification without a license is NOT permitted. Contact
|
modification without a license is NOT permitted. Contact
|
||||||
license@dorkbox.com for a license.
|
license@dorkbox.com for a license.
|
||||||
|
|
||||||
Neither the name of dorkbox, dorkbox llc, or dorkbox.com or the names of
|
Neither the name of dorkbox, dorkbox llc, or dorkbox.com or the names of
|
||||||
its contributors may be used to endorse or promote products derived from
|
its contributors may be used to endorse or promote products derived from
|
||||||
this software without specific prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
THE POSSIBILITY OF SUCH DAMAGE.
|
THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS
|
THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS
|
||||||
ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
||||||
PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
||||||
NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
||||||
SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE SOFTWARE
|
SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE SOFTWARE
|
||||||
COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR
|
COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR
|
||||||
ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").
|
ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").
|
||||||
|
|
||||||
THIS AGREEMENT IS GOVERNED THE INTELLECTUAL PROPERTY LAWS OF THE UNITED
|
THIS AGREEMENT IS GOVERNED THE INTELLECTUAL PROPERTY LAWS OF THE UNITED
|
||||||
STATES OF AMERICA. NO PARTY TO THIS AGREEMENT WILL BRING A LEGAL ACTION
|
STATES OF AMERICA. NO PARTY TO THIS AGREEMENT WILL BRING A LEGAL ACTION
|
||||||
UNDER THIS AGREEMENT MORE THAN ONE YEAR AFTER THE CAUSE OF ACTION AROSE.
|
UNDER THIS AGREEMENT MORE THAN ONE YEAR AFTER THE CAUSE OF ACTION AROSE.
|
||||||
EACH PARTY WAIVES ITS RIGHTS TO A JURY TRIAL IN ANY RESULTING LITIGATION.
|
EACH PARTY WAIVES ITS RIGHTS TO A JURY TRIAL IN ANY RESULTING LITIGATION.
|
||||||
|
|
||||||
|
@ -47,25 +47,25 @@ Legal:
|
||||||
https://bxa.ntis.gov/
|
https://bxa.ntis.gov/
|
||||||
|
|
||||||
Details of the U.S. Commercial Encryption Export Controls can be found at
|
Details of the U.S. Commercial Encryption Export Controls can be found at
|
||||||
the Bureau of Industry and Security (BIS) web site.
|
the Bureau of Industry and Security (BIS) web site.
|
||||||
http://www.bis.doc.gov/
|
http://www.bis.doc.gov/
|
||||||
|
|
||||||
PROHIBITED END USERS
|
PROHIBITED END USERS
|
||||||
ALL products are prohibited for export/reexport to the following:
|
ALL products are prohibited for export/reexport to the following:
|
||||||
|
|
||||||
- Any company or national of Cuba, Iran, North Korea, Sudan, and Syria.
|
- Any company or national of Cuba, Iran, North Korea, Sudan, and Syria.
|
||||||
Licenses to these countries and parties are presumed denied.
|
Licenses to these countries and parties are presumed denied.
|
||||||
|
|
||||||
- Re-export to these countries is prohibited; if you "know or have reason
|
- Re-export to these countries is prohibited; if you "know or have reason
|
||||||
to know" that an illegal reshipment will take place, you may not ship to
|
to know" that an illegal reshipment will take place, you may not ship to
|
||||||
such a user.
|
such a user.
|
||||||
|
|
||||||
- Entities listed on any U.S. Government Denied Party/Person List. See BIS's
|
- Entities listed on any U.S. Government Denied Party/Person List. See BIS's
|
||||||
The Denied Persons List, the Office of Foreign Assets Control's Economic
|
The Denied Persons List, the Office of Foreign Assets Control's Economic
|
||||||
and Trade sanctions list, (OFAC), and the Office of Defense Trade
|
and Trade sanctions list, (OFAC), and the Office of Defense Trade
|
||||||
Controls (DTC).
|
Controls (DTC).
|
||||||
|
|
||||||
- Any customer you know or have reason to know, who is involved in the
|
- Any customer you know or have reason to know, who is involved in the
|
||||||
design, development, manufacture or production of nuclear technology, or
|
design, development, manufacture or production of nuclear technology, or
|
||||||
nuclear, biological or chemical "weapons of mass destruction."
|
nuclear, biological or chemical "weapons of mass destruction."
|
||||||
|
|
||||||
|
@ -74,11 +74,19 @@ Legal:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- ArraysAsListSerializer,
|
||||||
|
UnmodifiableCollectionsSerializer - Apache 2.0 license
|
||||||
|
https://github.com/magro/kryo-serializers
|
||||||
|
Copyright 2010 Martin Grotzke
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- ASM - Bytecode manipulation framework and utilities - New BSD license
|
- ASM - Bytecode manipulation framework and utilities - New BSD license
|
||||||
http://asm.ow2.org/
|
http://asm.ow2.org/
|
||||||
Copyright (c) 2012 France Télécom
|
Copyright (c) 2012 France Télécom
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- BarchartUDT - BSD license
|
- BarchartUDT - BSD license
|
||||||
|
@ -90,17 +98,23 @@ Legal:
|
||||||
- BouncyCastle - MIT X11 License
|
- BouncyCastle - MIT X11 License
|
||||||
http://www.bouncycastle.org
|
http://www.bouncycastle.org
|
||||||
Copyright (c) 2000 - 2009 The Legion Of The Bouncy Castle
|
Copyright (c) 2000 - 2009 The Legion Of The Bouncy Castle
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- FieldAnnotationAwareSerializer - Apache 2.0 license
|
||||||
|
https://github.com/magro/kryo-serializers
|
||||||
|
Copyright 2010 Martin Grotzke, Rafael Winterhalter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- JAVASSIST - Apache 2.0 license
|
- JAVASSIST - Apache 2.0 license
|
||||||
http://www.csg.is.titech.ac.jp/~chiba/javassist/
|
http://www.csg.is.titech.ac.jp/~chiba/javassist/
|
||||||
Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
|
Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
|
||||||
Contributor(s): Bill Burke, Jason T. Greene
|
Contributor(s): Bill Burke, Jason T. Greene
|
||||||
Note: it is licensed under the MPL/LGPL/Apache triple license
|
Note: it is licensed under the MPL/LGPL/Apache triple license
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- JsonBeans, Kryo, Minlog (Minlog-SLF4J), ReflectASM - New BSD license
|
- JsonBeans, Kryo, Minlog (Minlog-SLF4J), ReflectASM - New BSD license
|
||||||
http://code.google.com/p/jsonbeans/
|
http://code.google.com/p/jsonbeans/
|
||||||
http://code.google.com/p/kryo/
|
http://code.google.com/p/kryo/
|
||||||
|
@ -115,34 +129,41 @@ Legal:
|
||||||
https://github.com/magro/kryo-serializers
|
https://github.com/magro/kryo-serializers
|
||||||
Copyright 2010 Martin Grotzke
|
Copyright 2010 Martin Grotzke
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- Logback - EPL v1.0
|
- Logback - EPL v1.0
|
||||||
http://logback.qos.ch/
|
http://logback.qos.ch/
|
||||||
Copyright (C) 1999-2012, QOS.ch. All rights reserved.
|
Copyright (C) 1999-2012, QOS.ch. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- MathUtils, IntArray, IntMap - Apache 2.0 license
|
- MathUtils, IntArray, IntMap - Apache 2.0 license
|
||||||
http://github.com/libgdx/libgdx/
|
http://github.com/libgdx/libgdx/
|
||||||
Copyright (c) 2013
|
Copyright (c) 2013
|
||||||
Mario Zechner <badlogicgames@gmail.com>
|
Mario Zechner <badlogicgames@gmail.com>
|
||||||
Nathan Sweet <nathan.sweet@gmail.com>
|
Nathan Sweet <nathan.sweet@gmail.com>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- MersenneTwisterFast, v20 - BSD license
|
||||||
|
http://www.cs.gmu.edu/~sean/research/mersenne/MersenneTwisterFast.java
|
||||||
|
Copyright (c) 2003 by Sean Luke.
|
||||||
|
Portions copyright (c) 1993 by Michael Lecuyer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- Netty - Apache 2.0 license
|
- Netty - Apache 2.0 license
|
||||||
http://netty.io
|
http://netty.io
|
||||||
Copyright (c) 2013 The Netty Project
|
Copyright (c) 2013 The Netty Project
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- Objenesis - Apache 2.0 license
|
- Objenesis - Apache 2.0 license
|
||||||
http://http://code.google.com/p/objenesis/
|
http://http://code.google.com/p/objenesis/
|
||||||
Copyright (c) 2003-2009, Joe Walnes, Henri Tremblay, Leonardo Mesquita
|
Copyright (c) 2003-2009, Joe Walnes, Henri Tremblay, Leonardo Mesquita
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- SLF4J - MIT license.
|
- SLF4J - MIT license.
|
||||||
http://www.slf4j.org/
|
http://www.slf4j.org/
|
||||||
Copyright (c) 2004-2008 QOS.ch
|
Copyright (c) 2004-2008 QOS.ch
|
||||||
|
@ -154,6 +175,7 @@ Legal:
|
||||||
http://udt.sourceforge.net/
|
http://udt.sourceforge.net/
|
||||||
Copyright 2001 - 2009, The Board of Trustees of the University of Illinois.
|
Copyright 2001 - 2009, The Board of Trustees of the University of Illinois.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@ import dorkbox.network.connection.registration.local.RegistrationLocalHandlerCli
|
||||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientTCP;
|
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientTCP;
|
||||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientUDP;
|
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientUDP;
|
||||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientUDT;
|
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerClientUDT;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.NamedThreadFactory;
|
import dorkbox.network.util.NamedThreadFactory;
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.network.util.udt.UdtEndpointProxy;
|
import dorkbox.network.util.udt.UdtEndpointProxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,9 +22,9 @@ import dorkbox.network.connection.registration.local.RegistrationLocalHandlerSer
|
||||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerTCP;
|
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerTCP;
|
||||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerUDP;
|
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerUDP;
|
||||||
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerUDT;
|
import dorkbox.network.connection.registration.remote.RegistrationRemoteHandlerServerUDT;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.NamedThreadFactory;
|
import dorkbox.network.util.NamedThreadFactory;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.network.util.udt.UdtEndpointProxy;
|
import dorkbox.network.util.udt.UdtEndpointProxy;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,16 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||||
import dorkbox.network.ConnectionOptions;
|
import dorkbox.network.ConnectionOptions;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.rmi.RmiBridge;
|
import dorkbox.network.rmi.RmiBridge;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.entropy.Entropy;
|
import dorkbox.network.util.entropy.Entropy;
|
||||||
import dorkbox.network.util.entropy.SimpleEntropy;
|
import dorkbox.network.util.entropy.SimpleEntropy;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.network.util.store.NullSettingsStore;
|
import dorkbox.network.util.store.NullSettingsStore;
|
||||||
import dorkbox.network.util.store.SettingsStore;
|
import dorkbox.network.util.store.SettingsStore;
|
||||||
import dorkbox.network.util.udt.UdtEndpointProxy;
|
import dorkbox.network.util.udt.UdtEndpointProxy;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
/** represents the base of a client/server end point */
|
/** represents the base of a client/server end point */
|
||||||
public abstract class EndPoint {
|
public abstract class EndPoint {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package dorkbox.network.connection;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import dorkbox.network.ConnectionOptions;
|
import dorkbox.network.ConnectionOptions;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This serves the purpose of making sure that specific methods are not available to the end user.
|
* This serves the purpose of making sure that specific methods are not available to the end user.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package dorkbox.network.connection;
|
package dorkbox.network.connection;
|
||||||
|
|
||||||
import dorkbox.network.ConnectionOptions;
|
import dorkbox.network.ConnectionOptions;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This serves the purpose of making sure that specific methods are not available to the end user.
|
* This serves the purpose of making sure that specific methods are not available to the end user.
|
||||||
|
|
|
@ -19,10 +19,10 @@ import dorkbox.network.connection.wrapper.ChannelWrapper;
|
||||||
import dorkbox.network.pipeline.KryoEncoder;
|
import dorkbox.network.pipeline.KryoEncoder;
|
||||||
import dorkbox.network.pipeline.KryoEncoderCrypto;
|
import dorkbox.network.pipeline.KryoEncoderCrypto;
|
||||||
import dorkbox.network.rmi.RmiBridge;
|
import dorkbox.network.rmi.RmiBridge;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.KryoSerializationManager;
|
import dorkbox.network.util.KryoSerializationManager;
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.util.crypto.serialization.EccPrivateKeySerializer;
|
import dorkbox.util.crypto.serialization.EccPrivateKeySerializer;
|
||||||
import dorkbox.util.crypto.serialization.EccPublicKeySerializer;
|
import dorkbox.util.crypto.serialization.EccPublicKeySerializer;
|
||||||
import dorkbox.util.crypto.serialization.IesParametersSerializer;
|
import dorkbox.util.crypto.serialization.IesParametersSerializer;
|
||||||
|
|
|
@ -59,7 +59,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Simple, property based method to getting the private key of the server
|
* Simple, property based method to getting the private key of the server
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized ECPrivateKeyParameters getPrivateKey() throws dorkbox.network.util.SecurityException {
|
public synchronized ECPrivateKeyParameters getPrivateKey() throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(EndPoint.class);
|
checkAccess(EndPoint.class);
|
||||||
|
|
||||||
return this.props.serverPrivateKey;
|
return this.props.serverPrivateKey;
|
||||||
|
@ -69,7 +69,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Simple, property based method for saving the private key of the server
|
* Simple, property based method for saving the private key of the server
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void savePrivateKey(ECPrivateKeyParameters serverPrivateKey) throws dorkbox.network.util.SecurityException {
|
public synchronized void savePrivateKey(ECPrivateKeyParameters serverPrivateKey) throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(EndPoint.class);
|
checkAccess(EndPoint.class);
|
||||||
|
|
||||||
this.props.serverPrivateKey = serverPrivateKey;
|
this.props.serverPrivateKey = serverPrivateKey;
|
||||||
|
@ -81,7 +81,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Simple, property based method to getting the public key of the server
|
* Simple, property based method to getting the public key of the server
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized ECPublicKeyParameters getPublicKey() throws dorkbox.network.util.SecurityException {
|
public synchronized ECPublicKeyParameters getPublicKey() throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(EndPoint.class);
|
checkAccess(EndPoint.class);
|
||||||
|
|
||||||
return this.props.serverPublicKey;
|
return this.props.serverPublicKey;
|
||||||
|
@ -91,7 +91,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Simple, property based method for saving the public key of the server
|
* Simple, property based method for saving the public key of the server
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void savePublicKey(ECPublicKeyParameters serverPublicKey) throws dorkbox.network.util.SecurityException {
|
public synchronized void savePublicKey(ECPublicKeyParameters serverPublicKey) throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(EndPoint.class);
|
checkAccess(EndPoint.class);
|
||||||
|
|
||||||
this.props.serverPublicKey = serverPublicKey;
|
this.props.serverPublicKey = serverPublicKey;
|
||||||
|
@ -122,7 +122,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Simple, property based method to getting a connected computer by host IP address
|
* Simple, property based method to getting a connected computer by host IP address
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized ECPublicKeyParameters getRegisteredServerKey(byte[] hostAddress) throws dorkbox.network.util.SecurityException {
|
public synchronized ECPublicKeyParameters getRegisteredServerKey(byte[] hostAddress) throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(RegistrationWrapper.class);
|
checkAccess(RegistrationWrapper.class);
|
||||||
|
|
||||||
return this.props.registeredServer.get(new ByteArrayWrapper(hostAddress));
|
return this.props.registeredServer.get(new ByteArrayWrapper(hostAddress));
|
||||||
|
@ -132,7 +132,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Saves a connected computer by host IP address and public key
|
* Saves a connected computer by host IP address and public key
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void addRegisteredServerKey(byte[] hostAddress, ECPublicKeyParameters publicKey) throws dorkbox.network.util.SecurityException {
|
public synchronized void addRegisteredServerKey(byte[] hostAddress, ECPublicKeyParameters publicKey) throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(RegistrationWrapper.class);
|
checkAccess(RegistrationWrapper.class);
|
||||||
|
|
||||||
this.props.registeredServer.put(new ByteArrayWrapper(hostAddress), publicKey);
|
this.props.registeredServer.put(new ByteArrayWrapper(hostAddress), publicKey);
|
||||||
|
@ -143,7 +143,7 @@ class PropertyStore extends SettingsStore {
|
||||||
* Deletes a registered computer by host IP address
|
* Deletes a registered computer by host IP address
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean removeRegisteredServerKey(byte[] hostAddress) throws dorkbox.network.util.SecurityException {
|
public synchronized boolean removeRegisteredServerKey(byte[] hostAddress) throws dorkbox.network.util.exceptions.SecurityException {
|
||||||
checkAccess(RegistrationWrapper.class);
|
checkAccess(RegistrationWrapper.class);
|
||||||
|
|
||||||
ECPublicKeyParameters remove = this.props.registeredServer.remove(new ByteArrayWrapper(hostAddress));
|
ECPublicKeyParameters remove = this.props.registeredServer.remove(new ByteArrayWrapper(hostAddress));
|
||||||
|
|
|
@ -16,9 +16,9 @@ import org.slf4j.Logger;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.pipeline.KryoEncoder;
|
import dorkbox.network.pipeline.KryoEncoder;
|
||||||
import dorkbox.network.pipeline.KryoEncoderCrypto;
|
import dorkbox.network.pipeline.KryoEncoderCrypto;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just wraps common/needed methods of the client/server endpoint by the registration stage/handshake.
|
* Just wraps common/needed methods of the client/server endpoint by the registration stage/handshake.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.util.NetException;
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
|
|
||||||
abstract public class InputStreamSender<C extends Connection> extends IdleSender<C,byte[]> {
|
abstract public class InputStreamSender<C extends Connection> extends IdleSender<C,byte[]> {
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import io.netty.channel.ChannelHandler.Sharable;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import dorkbox.network.connection.RegistrationWrapper;
|
import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
@Sharable
|
@Sharable
|
||||||
public abstract class RegistrationHandler extends ChannelInboundHandlerAdapter {
|
public abstract class RegistrationHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
|
@ -9,8 +9,8 @@ import dorkbox.network.connection.EndPoint;
|
||||||
import dorkbox.network.connection.RegistrationWrapper;
|
import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.RegistrationHandler;
|
import dorkbox.network.connection.registration.RegistrationHandler;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
public abstract class RegistrationLocalHandler extends RegistrationHandler {
|
public abstract class RegistrationLocalHandler extends RegistrationHandler {
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.RegistrationWrapper;
|
import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.Registration;
|
import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
|
||||||
public class RegistrationLocalHandlerClient extends RegistrationLocalHandler {
|
public class RegistrationLocalHandlerClient extends RegistrationLocalHandler {
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.slf4j.Logger;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.RegistrationWrapper;
|
import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
|
||||||
public class RegistrationLocalHandlerServer extends RegistrationLocalHandler {
|
public class RegistrationLocalHandlerServer extends RegistrationLocalHandler {
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ import dorkbox.network.pipeline.KryoDecoderCrypto;
|
||||||
import dorkbox.network.pipeline.udp.KryoDecoderUdpCrypto;
|
import dorkbox.network.pipeline.udp.KryoDecoderUdpCrypto;
|
||||||
import dorkbox.network.pipeline.udp.KryoEncoderUdpCrypto;
|
import dorkbox.network.pipeline.udp.KryoEncoderUdpCrypto;
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
public abstract class RegistrationRemoteHandler extends RegistrationHandler {
|
public abstract class RegistrationRemoteHandler extends RegistrationHandler {
|
||||||
private static final String IDLE_HANDLER_FULL = "idleHandlerFull";
|
private static final String IDLE_HANDLER_FULL = "idleHandlerFull";
|
||||||
|
|
|
@ -25,12 +25,12 @@ import com.esotericsoftware.kryo.io.Output;
|
||||||
import dorkbox.network.connection.RegistrationWrapper;
|
import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.Registration;
|
import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.util.bytes.OptimizeUtils;
|
import dorkbox.util.bytes.OptimizeUtils;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
import dorkbox.util.crypto.serialization.EccPublicKeySerializer;
|
import dorkbox.util.crypto.serialization.EccPublicKeySerializer;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
|
||||||
public class RegistrationRemoteHandlerClientTCP extends RegistrationRemoteHandlerClient {
|
public class RegistrationRemoteHandlerClientTCP extends RegistrationRemoteHandlerClient {
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.pipeline.udp.KryoDecoderUdp;
|
import dorkbox.network.pipeline.udp.KryoDecoderUdp;
|
||||||
import dorkbox.network.pipeline.udp.KryoEncoderUdp;
|
import dorkbox.network.pipeline.udp.KryoEncoderUdp;
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
|
||||||
import dorkbox.util.bytes.OptimizeUtils;
|
import dorkbox.util.bytes.OptimizeUtils;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
public class RegistrationRemoteHandlerClientUDP extends RegistrationRemoteHandlerClient {
|
public class RegistrationRemoteHandlerClientUDP extends RegistrationRemoteHandlerClient {
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.Registration;
|
import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
|
||||||
import dorkbox.util.bytes.OptimizeUtils;
|
import dorkbox.util.bytes.OptimizeUtils;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
|
|
||||||
public class RegistrationRemoteHandlerClientUDT extends RegistrationRemoteHandlerClient {
|
public class RegistrationRemoteHandlerClientUDT extends RegistrationRemoteHandlerClient {
|
||||||
|
|
|
@ -26,12 +26,12 @@ import com.esotericsoftware.kryo.io.Output;
|
||||||
import dorkbox.network.connection.RegistrationWrapper;
|
import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.Registration;
|
import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.util.RandomConnectionIdGenerator;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.util.MathUtils;
|
||||||
import dorkbox.util.bytes.OptimizeUtils;
|
import dorkbox.util.bytes.OptimizeUtils;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
import dorkbox.util.crypto.serialization.EccPublicKeySerializer;
|
import dorkbox.util.crypto.serialization.EccPublicKeySerializer;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
|
||||||
public class RegistrationRemoteHandlerServerTCP extends RegistrationRemoteHandlerServer {
|
public class RegistrationRemoteHandlerServerTCP extends RegistrationRemoteHandlerServer {
|
||||||
|
|
||||||
|
@ -160,13 +160,13 @@ public class RegistrationRemoteHandlerServerTCP extends RegistrationRemoteHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Integer connectionID = RandomConnectionIdGenerator.getRandom();
|
Integer connectionID = MathUtils.randomInt();
|
||||||
// if I'm unlucky, keep from confusing connections!
|
// if I'm unlucky, keep from confusing connections!
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IntMap<MetaChannel> channelMap = this.registrationWrapper.getAndLockChannelMap();
|
IntMap<MetaChannel> channelMap = this.registrationWrapper.getAndLockChannelMap();
|
||||||
while (channelMap.containsKey(connectionID)) {
|
while (channelMap.containsKey(connectionID)) {
|
||||||
connectionID = RandomConnectionIdGenerator.getRandom();
|
connectionID = MathUtils.randomInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
metaChannel.connectionID = connectionID;
|
metaChannel.connectionID = connectionID;
|
||||||
|
|
|
@ -22,12 +22,12 @@ import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.Registration;
|
import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.connection.wrapper.UdpWrapper;
|
import dorkbox.network.connection.wrapper.UdpWrapper;
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
|
||||||
import dorkbox.util.bytes.OptimizeUtils;
|
import dorkbox.util.bytes.OptimizeUtils;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
@Sharable
|
@Sharable
|
||||||
public class RegistrationRemoteHandlerServerUDP extends MessageToMessageCodec<DatagramPacket, UdpWrapper> {
|
public class RegistrationRemoteHandlerServerUDP extends MessageToMessageCodec<DatagramPacket, UdpWrapper> {
|
||||||
|
|
|
@ -11,10 +11,10 @@ import dorkbox.network.connection.RegistrationWrapper;
|
||||||
import dorkbox.network.connection.registration.MetaChannel;
|
import dorkbox.network.connection.registration.MetaChannel;
|
||||||
import dorkbox.network.connection.registration.Registration;
|
import dorkbox.network.connection.registration.Registration;
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
import dorkbox.network.util.primativeCollections.IntMap;
|
|
||||||
import dorkbox.network.util.primativeCollections.IntMap.Entries;
|
|
||||||
import dorkbox.util.bytes.OptimizeUtils;
|
import dorkbox.util.bytes.OptimizeUtils;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap;
|
||||||
|
import dorkbox.util.primativeCollections.IntMap.Entries;
|
||||||
|
|
||||||
public class RegistrationRemoteHandlerServerUDT extends RegistrationRemoteHandlerServer {
|
public class RegistrationRemoteHandlerServerUDT extends RegistrationRemoteHandlerServer {
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import io.netty.channel.Channel;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
import dorkbox.network.connection.UdpServer;
|
import dorkbox.network.connection.UdpServer;
|
||||||
import dorkbox.network.util.NetException;
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
|
|
||||||
public class ChannelNetworkUdp extends ChannelNetwork {
|
public class ChannelNetworkUdp extends ChannelNetwork {
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package dorkbox.network.pipeline;
|
package dorkbox.network.pipeline;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
|
@ -7,8 +7,8 @@ import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.KryoException;
|
import com.esotericsoftware.kryo.KryoException;
|
||||||
|
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
import dorkbox.util.bytes.OptimizeUtilsByteBuf;
|
import dorkbox.util.bytes.OptimizeUtilsByteBuf;
|
||||||
|
|
||||||
@Sharable
|
@Sharable
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package dorkbox.network.pipeline;
|
package dorkbox.network.pipeline;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandler.Sharable;
|
import io.netty.channel.ChannelHandler.Sharable;
|
||||||
|
|
|
@ -8,8 +8,8 @@ import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
|
|
||||||
@Sharable
|
@Sharable
|
||||||
public class KryoDecoderUdp extends MessageToMessageDecoder<DatagramPacket> {
|
public class KryoDecoderUdp extends MessageToMessageDecoder<DatagramPacket> {
|
||||||
|
|
|
@ -10,8 +10,8 @@ import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
|
|
||||||
@Sharable
|
@Sharable
|
||||||
public class KryoDecoderUdpCrypto extends MessageToMessageDecoder<DatagramPacket> {
|
public class KryoDecoderUdpCrypto extends MessageToMessageDecoder<DatagramPacket> {
|
||||||
|
|
|
@ -13,8 +13,8 @@ import java.util.List;
|
||||||
import com.esotericsoftware.kryo.KryoException;
|
import com.esotericsoftware.kryo.KryoException;
|
||||||
|
|
||||||
import dorkbox.network.connection.EndPoint;
|
import dorkbox.network.connection.EndPoint;
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
|
|
||||||
@Sharable
|
@Sharable
|
||||||
// UDP uses messages --- NOT bytebuf!
|
// UDP uses messages --- NOT bytebuf!
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package dorkbox.network.pipeline.udp;
|
package dorkbox.network.pipeline.udp;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.util.NetException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandler.Sharable;
|
import io.netty.channel.ChannelHandler.Sharable;
|
||||||
|
|
|
@ -30,8 +30,8 @@ import com.esotericsoftware.kryo.util.IntMap;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.EndPoint;
|
import dorkbox.network.connection.EndPoint;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.ObjectIntMap;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.util.primativeCollections.ObjectIntMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows methods on objects to be invoked remotely over TCP. Objects are
|
* Allows methods on objects to be invoked remotely over TCP. Objects are
|
||||||
|
|
|
@ -3,7 +3,7 @@ package dorkbox.network.util;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Necessary to provide equals and hashcode for byte arrays (if they are to be used in a map/set/etc)
|
* Necessary to provide equals and hashcode for byte arrays (if they are to be used as keys in a map/set/etc)
|
||||||
*/
|
*/
|
||||||
public final class ByteArrayWrapper {
|
public final class ByteArrayWrapper {
|
||||||
private final byte[] data;
|
private final byte[] data;
|
||||||
|
|
|
@ -28,6 +28,8 @@ import dorkbox.network.pipeline.ByteBufInput;
|
||||||
import dorkbox.network.pipeline.ByteBufOutput;
|
import dorkbox.network.pipeline.ByteBufOutput;
|
||||||
import dorkbox.network.rmi.RmiRegisterClassesCallback;
|
import dorkbox.network.rmi.RmiRegisterClassesCallback;
|
||||||
import dorkbox.network.rmi.SerializerRegistration;
|
import dorkbox.network.rmi.SerializerRegistration;
|
||||||
|
import dorkbox.network.util.exceptions.NetException;
|
||||||
|
import dorkbox.network.util.serializers.UnmodifiableCollectionsSerializer;
|
||||||
import dorkbox.util.crypto.Crypto;
|
import dorkbox.util.crypto.Crypto;
|
||||||
import dorkbox.util.crypto.bouncycastle.GCMBlockCipher_ByteBuf;
|
import dorkbox.util.crypto.bouncycastle.GCMBlockCipher_ByteBuf;
|
||||||
|
|
||||||
|
|
|
@ -1,559 +0,0 @@
|
||||||
|
|
||||||
package dorkbox.network.util;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.util.ObjectMap;
|
|
||||||
|
|
||||||
/** An unordered map where the values are ints. This implementation is a cuckoo hash map using 3 hashes, random walking, and a
|
|
||||||
* small stash for problematic keys. Null keys are not allowed. No allocation is done except when growing the table size. <br>
|
|
||||||
* <br>
|
|
||||||
* This map performs very fast get, containsKey, and remove (typically O(1), worst case O(log(n))). Put may be a bit slower,
|
|
||||||
* depending on hash collisions. Load factors greater than 0.91 greatly increase the chances the map will have to rehash to the
|
|
||||||
* next higher POT size.
|
|
||||||
* @author Nathan Sweet */
|
|
||||||
public class ObjectIntMap<K> {
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
|
||||||
private static final int PRIME3 = 0xced1c241;
|
|
||||||
|
|
||||||
static Random random = new Random();
|
|
||||||
|
|
||||||
public int size;
|
|
||||||
|
|
||||||
K[] keyTable;
|
|
||||||
int[] valueTable;
|
|
||||||
int capacity, stashSize;
|
|
||||||
|
|
||||||
private float loadFactor;
|
|
||||||
private int hashShift, mask, threshold;
|
|
||||||
private int stashCapacity;
|
|
||||||
private int pushIterations;
|
|
||||||
|
|
||||||
/** Creates a new map with an initial capacity of 32 and a load factor of 0.8. This map will hold 25 items before growing the
|
|
||||||
* backing table. */
|
|
||||||
public ObjectIntMap () {
|
|
||||||
this(32, 0.8f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new map with a load factor of 0.8. This map will hold initialCapacity * 0.8 items before growing the backing
|
|
||||||
* table. */
|
|
||||||
public ObjectIntMap (int initialCapacity) {
|
|
||||||
this(initialCapacity, 0.8f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new map with the specified initial capacity and load factor. This map will hold initialCapacity * loadFactor items
|
|
||||||
* before growing the backing table. */
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public ObjectIntMap (int initialCapacity, float loadFactor) {
|
|
||||||
if (initialCapacity < 0) {
|
|
||||||
throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
|
||||||
}
|
|
||||||
if (initialCapacity > 1 << 30) {
|
|
||||||
throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
|
||||||
}
|
|
||||||
capacity = ObjectMap.nextPowerOfTwo(initialCapacity);
|
|
||||||
|
|
||||||
if (loadFactor <= 0) {
|
|
||||||
throw new IllegalArgumentException("loadFactor must be > 0: " + loadFactor);
|
|
||||||
}
|
|
||||||
this.loadFactor = loadFactor;
|
|
||||||
|
|
||||||
threshold = (int)(capacity * loadFactor);
|
|
||||||
mask = capacity - 1;
|
|
||||||
hashShift = 31 - Integer.numberOfTrailingZeros(capacity);
|
|
||||||
stashCapacity = Math.max(3, (int)Math.ceil(Math.log(capacity)) * 2);
|
|
||||||
pushIterations = Math.max(Math.min(capacity, 8), (int)Math.sqrt(capacity) / 8);
|
|
||||||
|
|
||||||
keyTable = (K[])new Object[capacity + stashCapacity];
|
|
||||||
valueTable = new int[keyTable.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new map identical to the specified map. */
|
|
||||||
public ObjectIntMap (ObjectIntMap<? extends K> map) {
|
|
||||||
this(map.capacity, map.loadFactor);
|
|
||||||
stashSize = map.stashSize;
|
|
||||||
System.arraycopy(map.keyTable, 0, keyTable, 0, map.keyTable.length);
|
|
||||||
System.arraycopy(map.valueTable, 0, valueTable, 0, map.valueTable.length);
|
|
||||||
size = map.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put (K key, int value) {
|
|
||||||
if (key == null) {
|
|
||||||
throw new IllegalArgumentException("key cannot be null.");
|
|
||||||
}
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
|
|
||||||
// Check for existing keys.
|
|
||||||
int hashCode = key.hashCode();
|
|
||||||
int index1 = hashCode & mask;
|
|
||||||
K key1 = keyTable[index1];
|
|
||||||
if (key.equals(key1)) {
|
|
||||||
valueTable[index1] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index2 = hash2(hashCode);
|
|
||||||
K key2 = keyTable[index2];
|
|
||||||
if (key.equals(key2)) {
|
|
||||||
valueTable[index2] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index3 = hash3(hashCode);
|
|
||||||
K key3 = keyTable[index3];
|
|
||||||
if (key.equals(key3)) {
|
|
||||||
valueTable[index3] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update key in the stash.
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (key.equals(keyTable[i])) {
|
|
||||||
valueTable[i] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for empty buckets.
|
|
||||||
if (key1 == null) {
|
|
||||||
keyTable[index1] = key;
|
|
||||||
valueTable[index1] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key2 == null) {
|
|
||||||
keyTable[index2] = key;
|
|
||||||
valueTable[index2] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key3 == null) {
|
|
||||||
keyTable[index3] = key;
|
|
||||||
valueTable[index3] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
push(key, value, index1, key1, index2, key2, index3, key3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Skips checks for existing keys. */
|
|
||||||
private void putResize (K key, int value) {
|
|
||||||
// Check for empty buckets.
|
|
||||||
int hashCode = key.hashCode();
|
|
||||||
int index1 = hashCode & mask;
|
|
||||||
K key1 = keyTable[index1];
|
|
||||||
if (key1 == null) {
|
|
||||||
keyTable[index1] = key;
|
|
||||||
valueTable[index1] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index2 = hash2(hashCode);
|
|
||||||
K key2 = keyTable[index2];
|
|
||||||
if (key2 == null) {
|
|
||||||
keyTable[index2] = key;
|
|
||||||
valueTable[index2] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index3 = hash3(hashCode);
|
|
||||||
K key3 = keyTable[index3];
|
|
||||||
if (key3 == null) {
|
|
||||||
keyTable[index3] = key;
|
|
||||||
valueTable[index3] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
push(key, value, index1, key1, index2, key2, index3, key3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void push (K insertKey, int insertValue, int index1, K key1, int index2, K key2, int index3, K key3) {
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
int[] valueTable = this.valueTable;
|
|
||||||
int mask = this.mask;
|
|
||||||
|
|
||||||
// Push keys until an empty bucket is found.
|
|
||||||
K evictedKey;
|
|
||||||
int evictedValue;
|
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
|
||||||
do {
|
|
||||||
// Replace the key and value for one of the hashes.
|
|
||||||
switch (random.nextInt(3)) {
|
|
||||||
case 0:
|
|
||||||
evictedKey = key1;
|
|
||||||
evictedValue = valueTable[index1];
|
|
||||||
keyTable[index1] = insertKey;
|
|
||||||
valueTable[index1] = insertValue;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
evictedKey = key2;
|
|
||||||
evictedValue = valueTable[index2];
|
|
||||||
keyTable[index2] = insertKey;
|
|
||||||
valueTable[index2] = insertValue;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
evictedKey = key3;
|
|
||||||
evictedValue = valueTable[index3];
|
|
||||||
keyTable[index3] = insertKey;
|
|
||||||
valueTable[index3] = insertValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the evicted key hashes to an empty bucket, put it there and stop.
|
|
||||||
int hashCode = evictedKey.hashCode();
|
|
||||||
index1 = hashCode & mask;
|
|
||||||
key1 = keyTable[index1];
|
|
||||||
if (key1 == null) {
|
|
||||||
keyTable[index1] = evictedKey;
|
|
||||||
valueTable[index1] = evictedValue;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index2 = hash2(hashCode);
|
|
||||||
key2 = keyTable[index2];
|
|
||||||
if (key2 == null) {
|
|
||||||
keyTable[index2] = evictedKey;
|
|
||||||
valueTable[index2] = evictedValue;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index3 = hash3(hashCode);
|
|
||||||
key3 = keyTable[index3];
|
|
||||||
if (key3 == null) {
|
|
||||||
keyTable[index3] = evictedKey;
|
|
||||||
valueTable[index3] = evictedValue;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++i == pushIterations) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
insertKey = evictedKey;
|
|
||||||
insertValue = evictedValue;
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
putStash(evictedKey, evictedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void putStash (K key, int value) {
|
|
||||||
if (stashSize == stashCapacity) {
|
|
||||||
// Too many pushes occurred and the stash is full, increase the table size.
|
|
||||||
resize(capacity << 1);
|
|
||||||
put(key, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Store key in the stash.
|
|
||||||
int index = capacity + stashSize;
|
|
||||||
keyTable[index] = key;
|
|
||||||
valueTable[index] = value;
|
|
||||||
stashSize++;
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param defaultValue Returned if the key was not associated with a value. */
|
|
||||||
public int get (K key, int defaultValue) {
|
|
||||||
int hashCode = key.hashCode();
|
|
||||||
int index = hashCode & mask;
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
index = hash2(hashCode);
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
index = hash3(hashCode);
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
return getStash(key, defaultValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valueTable[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getStash (K key, int defaultValue) {
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (key.equals(keyTable[i])) {
|
|
||||||
return valueTable[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the key's current value and increments the stored value. If the key is not in the map, defaultValue + increment is
|
|
||||||
* put into the map. */
|
|
||||||
public int getAndIncrement (K key, int defaultValue, int increment) {
|
|
||||||
int hashCode = key.hashCode();
|
|
||||||
int index = hashCode & mask;
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
index = hash2(hashCode);
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
index = hash3(hashCode);
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
return getAndIncrementStash(key, defaultValue, increment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int value = valueTable[index];
|
|
||||||
valueTable[index] = value + increment;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getAndIncrementStash (K key, int defaultValue, int increment) {
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (key.equals(keyTable[i])) {
|
|
||||||
int value = valueTable[i];
|
|
||||||
valueTable[i] = value + increment;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
put(key, defaultValue + increment);
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int remove (K key, int defaultValue) {
|
|
||||||
int hashCode = key.hashCode();
|
|
||||||
int index = hashCode & mask;
|
|
||||||
if (key.equals(keyTable[index])) {
|
|
||||||
keyTable[index] = null;
|
|
||||||
int oldValue = valueTable[index];
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = hash2(hashCode);
|
|
||||||
if (key.equals(keyTable[index])) {
|
|
||||||
keyTable[index] = null;
|
|
||||||
int oldValue = valueTable[index];
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = hash3(hashCode);
|
|
||||||
if (key.equals(keyTable[index])) {
|
|
||||||
keyTable[index] = null;
|
|
||||||
int oldValue = valueTable[index];
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return removeStash(key, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
int removeStash (K key, int defaultValue) {
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (key.equals(keyTable[i])) {
|
|
||||||
int oldValue = valueTable[i];
|
|
||||||
removeStashIndex(i);
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeStashIndex (int index) {
|
|
||||||
// If the removed location was not last, move the last tuple to the removed location.
|
|
||||||
stashSize--;
|
|
||||||
int lastIndex = capacity + stashSize;
|
|
||||||
if (index < lastIndex) {
|
|
||||||
keyTable[index] = keyTable[lastIndex];
|
|
||||||
valueTable[index] = valueTable[lastIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reduces the size of the backing arrays to be the specified capacity or less. If the capacity is already less, nothing is
|
|
||||||
* done. If the map contains more items than the specified capacity, the next highest power of two capacity is used instead. */
|
|
||||||
public void shrink (int maximumCapacity) {
|
|
||||||
if (maximumCapacity < 0) {
|
|
||||||
throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
|
||||||
}
|
|
||||||
if (size > maximumCapacity) {
|
|
||||||
maximumCapacity = size;
|
|
||||||
}
|
|
||||||
if (capacity <= maximumCapacity) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
maximumCapacity = ObjectMap.nextPowerOfTwo(maximumCapacity);
|
|
||||||
resize(maximumCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Clears the map and reduces the size of the backing arrays to be the specified capacity if they are larger. */
|
|
||||||
public void clear (int maximumCapacity) {
|
|
||||||
if (capacity <= maximumCapacity) {
|
|
||||||
clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
size = 0;
|
|
||||||
resize(maximumCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear () {
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
keyTable[i] = null;
|
|
||||||
}
|
|
||||||
size = 0;
|
|
||||||
stashSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the specified value is in the map. Note this traverses the entire map and compares every value, which may be
|
|
||||||
* an expensive operation. */
|
|
||||||
public boolean containsValue (int value) {
|
|
||||||
int[] valueTable = this.valueTable;
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (valueTable[i] == value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsKey (K key) {
|
|
||||||
int hashCode = key.hashCode();
|
|
||||||
int index = hashCode & mask;
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
index = hash2(hashCode);
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
index = hash3(hashCode);
|
|
||||||
if (!key.equals(keyTable[index])) {
|
|
||||||
return containsKeyStash(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean containsKeyStash (K key) {
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (key.equals(keyTable[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the key for the specified value, or null if it is not in the map. Note this traverses the entire map and compares
|
|
||||||
* every value, which may be an expensive operation. */
|
|
||||||
public K findKey (int value) {
|
|
||||||
int[] valueTable = this.valueTable;
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (valueTable[i] == value) {
|
|
||||||
return keyTable[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Increases the size of the backing array to acommodate the specified number of additional items. Useful before adding many
|
|
||||||
* items to avoid multiple backing array resizes. */
|
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
|
||||||
int sizeNeeded = size + additionalCapacity;
|
|
||||||
if (sizeNeeded >= threshold) {
|
|
||||||
resize(ObjectMap.nextPowerOfTwo((int)(sizeNeeded / loadFactor)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void resize (int newSize) {
|
|
||||||
int oldEndIndex = capacity + stashSize;
|
|
||||||
|
|
||||||
capacity = newSize;
|
|
||||||
threshold = (int)(newSize * loadFactor);
|
|
||||||
mask = newSize - 1;
|
|
||||||
hashShift = 31 - Integer.numberOfTrailingZeros(newSize);
|
|
||||||
stashCapacity = Math.max(3, (int)Math.ceil(Math.log(newSize)) * 2);
|
|
||||||
pushIterations = Math.max(Math.min(newSize, 8), (int)Math.sqrt(newSize) / 8);
|
|
||||||
|
|
||||||
K[] oldKeyTable = keyTable;
|
|
||||||
int[] oldValueTable = valueTable;
|
|
||||||
|
|
||||||
keyTable = (K[])new Object[newSize + stashCapacity];
|
|
||||||
valueTable = new int[newSize + stashCapacity];
|
|
||||||
|
|
||||||
int oldSize = size;
|
|
||||||
size = 0;
|
|
||||||
stashSize = 0;
|
|
||||||
if (oldSize > 0) {
|
|
||||||
for (int i = 0; i < oldEndIndex; i++) {
|
|
||||||
K key = oldKeyTable[i];
|
|
||||||
if (key != null) {
|
|
||||||
putResize(key, oldValueTable[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int hash2 (int h) {
|
|
||||||
h *= PRIME2;
|
|
||||||
return (h ^ h >>> hashShift) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int hash3 (int h) {
|
|
||||||
h *= PRIME3;
|
|
||||||
return (h ^ h >>> hashShift) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString () {
|
|
||||||
if (size == 0) {
|
|
||||||
return "{}";
|
|
||||||
}
|
|
||||||
StringBuilder buffer = new StringBuilder(32);
|
|
||||||
buffer.append('{');
|
|
||||||
K[] keyTable = this.keyTable;
|
|
||||||
int[] valueTable = this.valueTable;
|
|
||||||
int i = keyTable.length;
|
|
||||||
while (i-- > 0) {
|
|
||||||
K key = keyTable[i];
|
|
||||||
if (key == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
buffer.append(key);
|
|
||||||
buffer.append('=');
|
|
||||||
buffer.append(valueTable[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (i-- > 0) {
|
|
||||||
K key = keyTable[i];
|
|
||||||
if (key == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
buffer.append(", ");
|
|
||||||
buffer.append(key);
|
|
||||||
buffer.append('=');
|
|
||||||
buffer.append(valueTable[i]);
|
|
||||||
}
|
|
||||||
buffer.append('}');
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package dorkbox.network.util;
|
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
|
|
||||||
public class RandomConnectionIdGenerator {
|
|
||||||
|
|
||||||
private static final SecureRandom secureRandom = new SecureRandom();
|
|
||||||
|
|
||||||
private static final ThreadLocal<Integer> uniqueNum =
|
|
||||||
new ThreadLocal<Integer>() {
|
|
||||||
@Override
|
|
||||||
protected Integer initialValue() {
|
|
||||||
return secureRandom.nextInt();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static Integer getRandom() {
|
|
||||||
return uniqueNum.get();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ import java.lang.reflect.Method;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
|
||||||
|
|
||||||
public class Entropy {
|
public class Entropy {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package dorkbox.network.util;
|
package dorkbox.network.util.exceptions;
|
||||||
|
|
||||||
public class InitializationException extends Exception {
|
public class InitializationException extends Exception {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
package dorkbox.network.util;
|
package dorkbox.network.util.exceptions;
|
||||||
|
|
||||||
public class NetException extends RuntimeException {
|
public class NetException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 2963139576811306988L;
|
private static final long serialVersionUID = 2963139576811306988L;
|
|
@ -1,4 +1,4 @@
|
||||||
package dorkbox.network.util;
|
package dorkbox.network.util.exceptions;
|
||||||
|
|
||||||
public class SecurityException extends Exception {
|
public class SecurityException extends Exception {
|
||||||
|
|
|
@ -1,381 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright 2011 See AUTHORS file.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// from libGDX
|
|
||||||
|
|
||||||
package dorkbox.network.util.primativeCollections;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/** A resizable, ordered or unordered int array. Avoids the boxing that occurs with ArrayList<Integer>. If unordered, this class
|
|
||||||
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
|
||||||
* @author Nathan Sweet */
|
|
||||||
public class IntArray {
|
|
||||||
public int[] items;
|
|
||||||
public int size;
|
|
||||||
public boolean ordered;
|
|
||||||
|
|
||||||
/** Creates an ordered array with a capacity of 16. */
|
|
||||||
public IntArray () {
|
|
||||||
this(true, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates an ordered array with the specified capacity. */
|
|
||||||
public IntArray (int capacity) {
|
|
||||||
this(true, capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param ordered If false, methods that remove elements may change the order of other elements in the array, which avoids a
|
|
||||||
* memory copy.
|
|
||||||
* @param capacity Any elements added beyond this will cause the backing array to be grown. */
|
|
||||||
public IntArray (boolean ordered, int capacity) {
|
|
||||||
this.ordered = ordered;
|
|
||||||
items = new int[capacity];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new array containing the elements in the specific array. The new array will be ordered if the specific array is
|
|
||||||
* ordered. The capacity is set to the number of elements, so any subsequent elements added will cause the backing array to be
|
|
||||||
* grown. */
|
|
||||||
public IntArray (IntArray array) {
|
|
||||||
this.ordered = array.ordered;
|
|
||||||
size = array.size;
|
|
||||||
items = new int[size];
|
|
||||||
System.arraycopy(array.items, 0, items, 0, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new ordered array containing the elements in the specified array. The capacity is set to the number of elements,
|
|
||||||
* so any subsequent elements added will cause the backing array to be grown. */
|
|
||||||
public IntArray (int[] array) {
|
|
||||||
this(true, array, 0, array.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new array containing the elements in the specified array. The capacity is set to the number of elements, so any
|
|
||||||
* subsequent elements added will cause the backing array to be grown.
|
|
||||||
* @param ordered If false, methods that remove elements may change the order of other elements in the array, which avoids a
|
|
||||||
* memory copy. */
|
|
||||||
public IntArray (boolean ordered, int[] array, int startIndex, int count) {
|
|
||||||
this(ordered, array.length);
|
|
||||||
size = count;
|
|
||||||
System.arraycopy(array, startIndex, items, 0, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add (int value) {
|
|
||||||
int[] items = this.items;
|
|
||||||
if (size == items.length) {
|
|
||||||
items = resize(Math.max(8, (int)(size * 1.75f)));
|
|
||||||
}
|
|
||||||
items[size++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAll (IntArray array) {
|
|
||||||
addAll(array, 0, array.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAll (IntArray array, int offset, int length) {
|
|
||||||
if (offset + length > array.size) {
|
|
||||||
throw new IllegalArgumentException("offset + length must be <= size: " + offset + " + " + length + " <= " + array.size);
|
|
||||||
}
|
|
||||||
addAll(array.items, offset, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAll (int[] array) {
|
|
||||||
addAll(array, 0, array.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAll (int[] array, int offset, int length) {
|
|
||||||
int[] items = this.items;
|
|
||||||
int sizeNeeded = size + length;
|
|
||||||
if (sizeNeeded >= items.length) {
|
|
||||||
items = resize(Math.max(8, (int)(sizeNeeded * 1.75f)));
|
|
||||||
}
|
|
||||||
System.arraycopy(array, offset, items, size, length);
|
|
||||||
size += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int get (int index) {
|
|
||||||
if (index >= size) {
|
|
||||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
|
||||||
}
|
|
||||||
return items[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set (int index, int value) {
|
|
||||||
if (index >= size) {
|
|
||||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
|
||||||
}
|
|
||||||
items[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert (int index, int value) {
|
|
||||||
if (index > size) {
|
|
||||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
|
||||||
}
|
|
||||||
int[] items = this.items;
|
|
||||||
if (size == items.length) {
|
|
||||||
items = resize(Math.max(8, (int)(size * 1.75f)));
|
|
||||||
}
|
|
||||||
if (ordered) {
|
|
||||||
System.arraycopy(items, index, items, index + 1, size - index);
|
|
||||||
} else {
|
|
||||||
items[size] = items[index];
|
|
||||||
}
|
|
||||||
size++;
|
|
||||||
items[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void swap (int first, int second) {
|
|
||||||
if (first >= size) {
|
|
||||||
throw new IndexOutOfBoundsException(String.valueOf(first));
|
|
||||||
}
|
|
||||||
if (second >= size) {
|
|
||||||
throw new IndexOutOfBoundsException(String.valueOf(second));
|
|
||||||
}
|
|
||||||
int[] items = this.items;
|
|
||||||
int firstValue = items[first];
|
|
||||||
items[first] = items[second];
|
|
||||||
items[second] = firstValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains (int value) {
|
|
||||||
int i = size - 1;
|
|
||||||
int[] items = this.items;
|
|
||||||
while (i >= 0) {
|
|
||||||
if (items[i--] == value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int indexOf (int value) {
|
|
||||||
int[] items = this.items;
|
|
||||||
for (int i = 0, n = size; i < n; i++) {
|
|
||||||
if (items[i] == value) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int lastIndexOf (int value) {
|
|
||||||
int[] items = this.items;
|
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
|
||||||
if (items[i] == value) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeValue (int value) {
|
|
||||||
int[] items = this.items;
|
|
||||||
for (int i = 0, n = size; i < n; i++) {
|
|
||||||
if (items[i] == value) {
|
|
||||||
removeIndex(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes and returns the item at the specified index. */
|
|
||||||
public int removeIndex (int index) {
|
|
||||||
if (index >= size) {
|
|
||||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
|
||||||
}
|
|
||||||
int[] items = this.items;
|
|
||||||
int value = items[index];
|
|
||||||
size--;
|
|
||||||
if (ordered) {
|
|
||||||
System.arraycopy(items, index + 1, items, index, size - index);
|
|
||||||
} else {
|
|
||||||
items[index] = items[size];
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes from this array all of elements contained in the specified array.
|
|
||||||
* @return true if this array was modified. */
|
|
||||||
public boolean removeAll (IntArray array) {
|
|
||||||
int size = this.size;
|
|
||||||
int startSize = size;
|
|
||||||
int[] items = this.items;
|
|
||||||
for (int i = 0, n = array.size; i < n; i++) {
|
|
||||||
int item = array.get(i);
|
|
||||||
for (int ii = 0; ii < size; ii++) {
|
|
||||||
if (item == items[ii]) {
|
|
||||||
removeIndex(ii);
|
|
||||||
size--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return size != startSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes and returns the last item. */
|
|
||||||
public int pop () {
|
|
||||||
return items[--size];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the last item. */
|
|
||||||
public int peek () {
|
|
||||||
return items[size - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the first item. */
|
|
||||||
public int first () {
|
|
||||||
if (size == 0) {
|
|
||||||
throw new IllegalStateException("Array is empty.");
|
|
||||||
}
|
|
||||||
return items[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear () {
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reduces the size of the backing array to the size of the actual items. This is useful to release memory when many items have
|
|
||||||
* been removed, or if it is known that more items will not be added. */
|
|
||||||
public void shrink () {
|
|
||||||
resize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Increases the size of the backing array to acommodate the specified number of additional items. Useful before adding many
|
|
||||||
* items to avoid multiple backing array resizes.
|
|
||||||
* @return {@link #items} */
|
|
||||||
public int[] ensureCapacity (int additionalCapacity) {
|
|
||||||
int sizeNeeded = size + additionalCapacity;
|
|
||||||
if (sizeNeeded >= items.length) {
|
|
||||||
resize(Math.max(8, sizeNeeded));
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int[] resize (int newSize) {
|
|
||||||
int[] newItems = new int[newSize];
|
|
||||||
int[] items = this.items;
|
|
||||||
System.arraycopy(items, 0, newItems, 0, Math.min(size, newItems.length));
|
|
||||||
this.items = newItems;
|
|
||||||
return newItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sort () {
|
|
||||||
Arrays.sort(items, 0, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reverse () {
|
|
||||||
for (int i = 0, lastIndex = size - 1, n = size / 2; i < n; i++) {
|
|
||||||
int ii = lastIndex - i;
|
|
||||||
int temp = items[i];
|
|
||||||
items[i] = items[ii];
|
|
||||||
items[ii] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void shuffle () {
|
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
|
||||||
int ii = MathUtils.random(i);
|
|
||||||
int temp = items[i];
|
|
||||||
items[i] = items[ii];
|
|
||||||
items[ii] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reduces the size of the array to the specified size. If the array is already smaller than the specified size, no action is
|
|
||||||
* taken. */
|
|
||||||
public void truncate (int newSize) {
|
|
||||||
if (size > newSize) {
|
|
||||||
size = newSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a random item from the array, or zero if the array is empty. */
|
|
||||||
public int random () {
|
|
||||||
if (size == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return items[MathUtils.random(0, size - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] toArray () {
|
|
||||||
int[] array = new int[size];
|
|
||||||
System.arraycopy(items, 0, array, 0, size);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + Arrays.hashCode(this.items);
|
|
||||||
result = prime * result + (this.ordered ? 1231 : 1237);
|
|
||||||
result = prime * result + this.size;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals (Object object) {
|
|
||||||
if (object == this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(object instanceof IntArray)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
IntArray array = (IntArray)object;
|
|
||||||
int n = size;
|
|
||||||
if (n != array.size) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (items[i] != array.items[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString () {
|
|
||||||
if (size == 0) {
|
|
||||||
return "[]";
|
|
||||||
}
|
|
||||||
int[] items = this.items;
|
|
||||||
StringBuilder buffer = new StringBuilder(32);
|
|
||||||
buffer.append('[');
|
|
||||||
buffer.append(items[0]);
|
|
||||||
for (int i = 1; i < size; i++) {
|
|
||||||
buffer.append(", ");
|
|
||||||
buffer.append(items[i]);
|
|
||||||
}
|
|
||||||
buffer.append(']');
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString (String separator) {
|
|
||||||
if (size == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
int[] items = this.items;
|
|
||||||
StringBuilder buffer = new StringBuilder(32);
|
|
||||||
buffer.append(items[0]);
|
|
||||||
for (int i = 1; i < size; i++) {
|
|
||||||
buffer.append(separator);
|
|
||||||
buffer.append(items[i]);
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,867 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright 2011 See AUTHORS file.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// slightly tweaked from libGDX
|
|
||||||
|
|
||||||
package dorkbox.network.util.primativeCollections;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
|
|
||||||
/** An unordered map that uses int keys. This implementation is a cuckoo hash map using 3 hashes, random walking, and a small stash
|
|
||||||
* for problematic keys. Null values are allowed. No allocation is done except when growing the table size. <br>
|
|
||||||
* <br>
|
|
||||||
* This map performs very fast get, containsKey, and remove (typically O(1), worst case O(log(n))). Put may be a bit slower,
|
|
||||||
* depending on hash collisions. Load factors greater than 0.91 greatly increase the chances the map will have to rehash to the
|
|
||||||
* next higher POT size.
|
|
||||||
* @author Nathan Sweet */
|
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
public class IntMap<V> {
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
|
||||||
private static final int PRIME3 = 0xced1c241;
|
|
||||||
private static final int EMPTY = 0;
|
|
||||||
|
|
||||||
public int size;
|
|
||||||
|
|
||||||
int[] keyTable;
|
|
||||||
V[] valueTable;
|
|
||||||
int capacity, stashSize;
|
|
||||||
V zeroValue;
|
|
||||||
boolean hasZeroValue;
|
|
||||||
|
|
||||||
private float loadFactor;
|
|
||||||
private int hashShift, mask, threshold;
|
|
||||||
private int stashCapacity;
|
|
||||||
private int pushIterations;
|
|
||||||
|
|
||||||
private Entries entries1, entries2;
|
|
||||||
private Values values1, values2;
|
|
||||||
private Keys keys1, keys2;
|
|
||||||
|
|
||||||
/** Creates a new map with an initial capacity of 32 and a load factor of 0.8. This map will hold 25 items before growing the
|
|
||||||
* backing table. */
|
|
||||||
public IntMap () {
|
|
||||||
this(32, 0.8f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new map with a load factor of 0.8. This map will hold initialCapacity * 0.8 items before growing the backing
|
|
||||||
* table. */
|
|
||||||
public IntMap (int initialCapacity) {
|
|
||||||
this(initialCapacity, 0.8f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates a new map with the specified initial capacity and load factor. This map will hold initialCapacity * loadFactor items
|
|
||||||
* before growing the backing table. */
|
|
||||||
public IntMap (int initialCapacity, float loadFactor) {
|
|
||||||
if (initialCapacity < 0) {
|
|
||||||
throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
|
||||||
}
|
|
||||||
if (capacity > 1 << 30) {
|
|
||||||
throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
|
||||||
}
|
|
||||||
capacity = MathUtils.nextPowerOfTwo(initialCapacity);
|
|
||||||
|
|
||||||
if (loadFactor <= 0) {
|
|
||||||
throw new IllegalArgumentException("loadFactor must be > 0: " + loadFactor);
|
|
||||||
}
|
|
||||||
this.loadFactor = loadFactor;
|
|
||||||
|
|
||||||
threshold = (int)(capacity * loadFactor);
|
|
||||||
mask = capacity - 1;
|
|
||||||
hashShift = 31 - Integer.numberOfTrailingZeros(capacity);
|
|
||||||
stashCapacity = Math.max(3, (int)Math.ceil(Math.log(capacity)) * 2);
|
|
||||||
pushIterations = Math.max(Math.min(capacity, 8), (int)Math.sqrt(capacity) / 8);
|
|
||||||
|
|
||||||
keyTable = new int[capacity + stashCapacity];
|
|
||||||
valueTable = (V[])new Object[keyTable.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
public V put (int key, V value) {
|
|
||||||
if (key == 0) {
|
|
||||||
V oldValue = zeroValue;
|
|
||||||
zeroValue = value;
|
|
||||||
if (!hasZeroValue) {
|
|
||||||
hasZeroValue = true;
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
|
|
||||||
// Check for existing keys.
|
|
||||||
int index1 = key & mask;
|
|
||||||
int key1 = keyTable[index1];
|
|
||||||
if (key1 == key) {
|
|
||||||
V oldValue = valueTable[index1];
|
|
||||||
valueTable[index1] = value;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index2 = hash2(key);
|
|
||||||
int key2 = keyTable[index2];
|
|
||||||
if (key2 == key) {
|
|
||||||
V oldValue = valueTable[index2];
|
|
||||||
valueTable[index2] = value;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index3 = hash3(key);
|
|
||||||
int key3 = keyTable[index3];
|
|
||||||
if (key3 == key) {
|
|
||||||
V oldValue = valueTable[index3];
|
|
||||||
valueTable[index3] = value;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update key in the stash.
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (keyTable[i] == key) {
|
|
||||||
V oldValue = valueTable[i];
|
|
||||||
valueTable[i] = value;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for empty buckets.
|
|
||||||
if (key1 == EMPTY) {
|
|
||||||
keyTable[index1] = key;
|
|
||||||
valueTable[index1] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key2 == EMPTY) {
|
|
||||||
keyTable[index2] = key;
|
|
||||||
valueTable[index2] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key3 == EMPTY) {
|
|
||||||
keyTable[index3] = key;
|
|
||||||
valueTable[index3] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
push(key, value, index1, key1, index2, key2, index3, key3);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void putAll (IntMap<V> map) {
|
|
||||||
for (Entry<V> entry : map.entries()) {
|
|
||||||
put(entry.key, entry.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Skips checks for existing keys. */
|
|
||||||
private void putResize (int key, V value) {
|
|
||||||
if (key == 0) {
|
|
||||||
zeroValue = value;
|
|
||||||
hasZeroValue = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for empty buckets.
|
|
||||||
int index1 = key & mask;
|
|
||||||
int key1 = keyTable[index1];
|
|
||||||
if (key1 == EMPTY) {
|
|
||||||
keyTable[index1] = key;
|
|
||||||
valueTable[index1] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index2 = hash2(key);
|
|
||||||
int key2 = keyTable[index2];
|
|
||||||
if (key2 == EMPTY) {
|
|
||||||
keyTable[index2] = key;
|
|
||||||
valueTable[index2] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index3 = hash3(key);
|
|
||||||
int key3 = keyTable[index3];
|
|
||||||
if (key3 == EMPTY) {
|
|
||||||
keyTable[index3] = key;
|
|
||||||
valueTable[index3] = value;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
push(key, value, index1, key1, index2, key2, index3, key3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void push (int insertKey, V insertValue, int index1, int key1, int index2, int key2, int index3, int key3) {
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
|
|
||||||
V[] valueTable = this.valueTable;
|
|
||||||
int mask = this.mask;
|
|
||||||
|
|
||||||
// Push keys until an empty bucket is found.
|
|
||||||
int evictedKey;
|
|
||||||
V evictedValue;
|
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
|
||||||
do {
|
|
||||||
// Replace the key and value for one of the hashes.
|
|
||||||
switch (MathUtils.random(2)) {
|
|
||||||
case 0:
|
|
||||||
evictedKey = key1;
|
|
||||||
evictedValue = valueTable[index1];
|
|
||||||
keyTable[index1] = insertKey;
|
|
||||||
valueTable[index1] = insertValue;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
evictedKey = key2;
|
|
||||||
evictedValue = valueTable[index2];
|
|
||||||
keyTable[index2] = insertKey;
|
|
||||||
valueTable[index2] = insertValue;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
evictedKey = key3;
|
|
||||||
evictedValue = valueTable[index3];
|
|
||||||
keyTable[index3] = insertKey;
|
|
||||||
valueTable[index3] = insertValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the evicted key hashes to an empty bucket, put it there and stop.
|
|
||||||
index1 = evictedKey & mask;
|
|
||||||
key1 = keyTable[index1];
|
|
||||||
if (key1 == EMPTY) {
|
|
||||||
keyTable[index1] = evictedKey;
|
|
||||||
valueTable[index1] = evictedValue;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index2 = hash2(evictedKey);
|
|
||||||
key2 = keyTable[index2];
|
|
||||||
if (key2 == EMPTY) {
|
|
||||||
keyTable[index2] = evictedKey;
|
|
||||||
valueTable[index2] = evictedValue;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index3 = hash3(evictedKey);
|
|
||||||
key3 = keyTable[index3];
|
|
||||||
if (key3 == EMPTY) {
|
|
||||||
keyTable[index3] = evictedKey;
|
|
||||||
valueTable[index3] = evictedValue;
|
|
||||||
if (size++ >= threshold) {
|
|
||||||
resize(capacity << 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++i == pushIterations) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
insertKey = evictedKey;
|
|
||||||
insertValue = evictedValue;
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
putStash(evictedKey, evictedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void putStash (int key, V value) {
|
|
||||||
if (stashSize == stashCapacity) {
|
|
||||||
// Too many pushes occurred and the stash is full, increase the table size.
|
|
||||||
resize(capacity << 1);
|
|
||||||
put(key, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Store key in the stash.
|
|
||||||
int index = capacity + stashSize;
|
|
||||||
keyTable[index] = key;
|
|
||||||
valueTable[index] = value;
|
|
||||||
stashSize++;
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public V get (int key) {
|
|
||||||
if (key == 0) {
|
|
||||||
if (!hasZeroValue) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return zeroValue;
|
|
||||||
}
|
|
||||||
int index = key & mask;
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
index = hash2(key);
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
index = hash3(key);
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
return getStash(key, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valueTable[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public V get (int key, V defaultValue) {
|
|
||||||
if (key == 0) {
|
|
||||||
if (!hasZeroValue) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return zeroValue;
|
|
||||||
}
|
|
||||||
int index = key & mask;
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
index = hash2(key);
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
index = hash3(key);
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
return getStash(key, defaultValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return valueTable[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private V getStash (int key, V defaultValue) {
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (keyTable[i] == key) {
|
|
||||||
return valueTable[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public V remove (int key) {
|
|
||||||
if (key == 0) {
|
|
||||||
if (!hasZeroValue) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
V oldValue = zeroValue;
|
|
||||||
zeroValue = null;
|
|
||||||
hasZeroValue = false;
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = key & mask;
|
|
||||||
if (keyTable[index] == key) {
|
|
||||||
keyTable[index] = EMPTY;
|
|
||||||
V oldValue = valueTable[index];
|
|
||||||
valueTable[index] = null;
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = hash2(key);
|
|
||||||
if (keyTable[index] == key) {
|
|
||||||
keyTable[index] = EMPTY;
|
|
||||||
V oldValue = valueTable[index];
|
|
||||||
valueTable[index] = null;
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = hash3(key);
|
|
||||||
if (keyTable[index] == key) {
|
|
||||||
keyTable[index] = EMPTY;
|
|
||||||
V oldValue = valueTable[index];
|
|
||||||
valueTable[index] = null;
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return removeStash(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
V removeStash (int key) {
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (keyTable[i] == key) {
|
|
||||||
V oldValue = valueTable[i];
|
|
||||||
removeStashIndex(i);
|
|
||||||
size--;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeStashIndex (int index) {
|
|
||||||
// If the removed location was not last, move the last tuple to the removed location.
|
|
||||||
stashSize--;
|
|
||||||
int lastIndex = capacity + stashSize;
|
|
||||||
if (index < lastIndex) {
|
|
||||||
keyTable[index] = keyTable[lastIndex];
|
|
||||||
valueTable[index] = valueTable[lastIndex];
|
|
||||||
valueTable[lastIndex] = null;
|
|
||||||
} else {
|
|
||||||
valueTable[index] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear () {
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
V[] valueTable = this.valueTable;
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
keyTable[i] = EMPTY;
|
|
||||||
valueTable[i] = null;
|
|
||||||
}
|
|
||||||
size = 0;
|
|
||||||
stashSize = 0;
|
|
||||||
zeroValue = null;
|
|
||||||
hasZeroValue = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if the specified value is in the map. Note this traverses the entire map and compares every value, which may be
|
|
||||||
* an expensive operation.
|
|
||||||
* @param identity If true, uses == to compare the specified value with values in the map. If false, uses
|
|
||||||
* {@link #equals(Object)}. */
|
|
||||||
public boolean containsValue (Object value, boolean identity) {
|
|
||||||
V[] valueTable = this.valueTable;
|
|
||||||
if (value == null) {
|
|
||||||
if (hasZeroValue && zeroValue == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (keyTable[i] != EMPTY && valueTable[i] == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (identity) {
|
|
||||||
if (value == zeroValue) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (valueTable[i] == value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (hasZeroValue && value.equals(zeroValue)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (value.equals(valueTable[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsKey (int key) {
|
|
||||||
if (key == 0) {
|
|
||||||
return hasZeroValue;
|
|
||||||
}
|
|
||||||
int index = key & mask;
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
index = hash2(key);
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
index = hash3(key);
|
|
||||||
if (keyTable[index] != key) {
|
|
||||||
return containsKeyStash(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean containsKeyStash (int key) {
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity, n = i + stashSize; i < n; i++) {
|
|
||||||
if (keyTable[i] == key) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the key for the specified value, or <tt>notFound</tt> if it is not in the map. Note this traverses the entire map
|
|
||||||
* and compares every value, which may be an expensive operation.
|
|
||||||
* @param identity If true, uses == to compare the specified value with values in the map. If false, uses
|
|
||||||
* {@link #equals(Object)}. */
|
|
||||||
public int findKey (Object value, boolean identity, int notFound) {
|
|
||||||
V[] valueTable = this.valueTable;
|
|
||||||
if (value == null) {
|
|
||||||
if (hasZeroValue && zeroValue == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (keyTable[i] != EMPTY && valueTable[i] == null) {
|
|
||||||
return keyTable[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (identity) {
|
|
||||||
if (value == zeroValue) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (valueTable[i] == value) {
|
|
||||||
return keyTable[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (hasZeroValue && value.equals(zeroValue)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (int i = capacity + stashSize; i-- > 0;) {
|
|
||||||
if (value.equals(valueTable[i])) {
|
|
||||||
return keyTable[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return notFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Increases the size of the backing array to acommodate the specified number of additional items. Useful before adding many
|
|
||||||
* items to avoid multiple backing array resizes. */
|
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
|
||||||
int sizeNeeded = size + additionalCapacity;
|
|
||||||
if (sizeNeeded >= threshold) {
|
|
||||||
resize(MathUtils.nextPowerOfTwo((int)(sizeNeeded / loadFactor)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resize (int newSize) {
|
|
||||||
int oldEndIndex = capacity + stashSize;
|
|
||||||
|
|
||||||
capacity = newSize;
|
|
||||||
threshold = (int)(newSize * loadFactor);
|
|
||||||
mask = newSize - 1;
|
|
||||||
hashShift = 31 - Integer.numberOfTrailingZeros(newSize);
|
|
||||||
stashCapacity = Math.max(3, (int)Math.ceil(Math.log(newSize)) * 2);
|
|
||||||
pushIterations = Math.max(Math.min(newSize, 8), (int)Math.sqrt(newSize) / 8);
|
|
||||||
|
|
||||||
int[] oldKeyTable = keyTable;
|
|
||||||
V[] oldValueTable = valueTable;
|
|
||||||
|
|
||||||
keyTable = new int[newSize + stashCapacity];
|
|
||||||
valueTable = (V[])new Object[newSize + stashCapacity];
|
|
||||||
|
|
||||||
size = hasZeroValue ? 1 : 0;
|
|
||||||
stashSize = 0;
|
|
||||||
for (int i = 0; i < oldEndIndex; i++) {
|
|
||||||
int key = oldKeyTable[i];
|
|
||||||
if (key != EMPTY) {
|
|
||||||
putResize(key, oldValueTable[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int hash2 (int h) {
|
|
||||||
h *= PRIME2;
|
|
||||||
return (h ^ h >>> hashShift) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int hash3 (int h) {
|
|
||||||
h *= PRIME3;
|
|
||||||
return (h ^ h >>> hashShift) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString () {
|
|
||||||
if (size == 0) {
|
|
||||||
return "[]";
|
|
||||||
}
|
|
||||||
StringBuilder buffer = new StringBuilder(32);
|
|
||||||
buffer.append('[');
|
|
||||||
int[] keyTable = this.keyTable;
|
|
||||||
V[] valueTable = this.valueTable;
|
|
||||||
int i = keyTable.length;
|
|
||||||
if (hasZeroValue) {
|
|
||||||
buffer.append("0=");
|
|
||||||
buffer.append(zeroValue);
|
|
||||||
} else {
|
|
||||||
while (i-- > 0) {
|
|
||||||
int key = keyTable[i];
|
|
||||||
if (key == EMPTY) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
buffer.append(key);
|
|
||||||
buffer.append('=');
|
|
||||||
buffer.append(valueTable[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (i-- > 0) {
|
|
||||||
int key = keyTable[i];
|
|
||||||
if (key == EMPTY) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
buffer.append(", ");
|
|
||||||
buffer.append(key);
|
|
||||||
buffer.append('=');
|
|
||||||
buffer.append(valueTable[i]);
|
|
||||||
}
|
|
||||||
buffer.append(']');
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns an iterator for the entries in the map. Remove is supported. Note that the same iterator instance is returned each
|
|
||||||
* time this method is called. Use the {@link Entries} constructor for nested or multithreaded iteration. */
|
|
||||||
public Entries<V> entries () {
|
|
||||||
if (entries1 == null) {
|
|
||||||
entries1 = new Entries(this);
|
|
||||||
entries2 = new Entries(this);
|
|
||||||
}
|
|
||||||
if (!entries1.valid) {
|
|
||||||
entries1.reset();
|
|
||||||
entries1.valid = true;
|
|
||||||
entries2.valid = false;
|
|
||||||
return entries1;
|
|
||||||
}
|
|
||||||
entries2.reset();
|
|
||||||
entries2.valid = true;
|
|
||||||
entries1.valid = false;
|
|
||||||
return entries2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns an iterator for the values in the map. Remove is supported. Note that the same iterator instance is returned each
|
|
||||||
* time this method is called. Use the {@link Entries} constructor for nested or multithreaded iteration. */
|
|
||||||
public Values<V> values () {
|
|
||||||
if (values1 == null) {
|
|
||||||
values1 = new Values(this);
|
|
||||||
values2 = new Values(this);
|
|
||||||
}
|
|
||||||
if (!values1.valid) {
|
|
||||||
values1.reset();
|
|
||||||
values1.valid = true;
|
|
||||||
values2.valid = false;
|
|
||||||
return values1;
|
|
||||||
}
|
|
||||||
values2.reset();
|
|
||||||
values2.valid = true;
|
|
||||||
values1.valid = false;
|
|
||||||
return values2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns an iterator for the keys in the map. Remove is supported. Note that the same iterator instance is returned each time
|
|
||||||
* this method is called. Use the {@link Entries} constructor for nested or multithreaded iteration. */
|
|
||||||
public Keys keys () {
|
|
||||||
if (keys1 == null) {
|
|
||||||
keys1 = new Keys(this);
|
|
||||||
keys2 = new Keys(this);
|
|
||||||
}
|
|
||||||
if (!keys1.valid) {
|
|
||||||
keys1.reset();
|
|
||||||
keys1.valid = true;
|
|
||||||
keys2.valid = false;
|
|
||||||
return keys1;
|
|
||||||
}
|
|
||||||
keys2.reset();
|
|
||||||
keys2.valid = true;
|
|
||||||
keys1.valid = false;
|
|
||||||
return keys2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public class Entry<V> {
|
|
||||||
public int key;
|
|
||||||
public V value;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString () {
|
|
||||||
return key + "=" + value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static private class MapIterator<V> {
|
|
||||||
static final int INDEX_ILLEGAL = -2;
|
|
||||||
static final int INDEX_ZERO = -1;
|
|
||||||
|
|
||||||
public boolean hasNext;
|
|
||||||
|
|
||||||
final IntMap<V> map;
|
|
||||||
int nextIndex, currentIndex;
|
|
||||||
boolean valid = true;
|
|
||||||
|
|
||||||
public MapIterator (IntMap<V> map) {
|
|
||||||
this.map = map;
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset () {
|
|
||||||
currentIndex = INDEX_ILLEGAL;
|
|
||||||
nextIndex = INDEX_ZERO;
|
|
||||||
if (map.hasZeroValue) {
|
|
||||||
hasNext = true;
|
|
||||||
} else {
|
|
||||||
findNextIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void findNextIndex () {
|
|
||||||
hasNext = false;
|
|
||||||
int[] keyTable = map.keyTable;
|
|
||||||
for (int n = map.capacity + map.stashSize; ++nextIndex < n;) {
|
|
||||||
if (keyTable[nextIndex] != EMPTY) {
|
|
||||||
hasNext = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove () {
|
|
||||||
if (currentIndex == INDEX_ZERO && map.hasZeroValue) {
|
|
||||||
map.zeroValue = null;
|
|
||||||
map.hasZeroValue = false;
|
|
||||||
} else if (currentIndex < 0) {
|
|
||||||
throw new IllegalStateException("next must be called before remove.");
|
|
||||||
} else if (currentIndex >= map.capacity) {
|
|
||||||
map.removeStashIndex(currentIndex);
|
|
||||||
} else {
|
|
||||||
map.keyTable[currentIndex] = EMPTY;
|
|
||||||
map.valueTable[currentIndex] = null;
|
|
||||||
}
|
|
||||||
currentIndex = INDEX_ILLEGAL;
|
|
||||||
map.size--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static public class Entries<V> extends MapIterator<V> implements Iterable<Entry<V>>, Iterator<Entry<V>> {
|
|
||||||
private Entry<V> entry = new Entry();
|
|
||||||
|
|
||||||
public Entries (IntMap map) {
|
|
||||||
super(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Note the same entry instance is returned each time this method is called. */
|
|
||||||
@Override
|
|
||||||
public Entry<V> next () {
|
|
||||||
if (!hasNext) {
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
throw new RuntimeException("#iterator() cannot be used nested.");
|
|
||||||
}
|
|
||||||
int[] keyTable = map.keyTable;
|
|
||||||
if (nextIndex == INDEX_ZERO) {
|
|
||||||
entry.key = 0;
|
|
||||||
entry.value = map.zeroValue;
|
|
||||||
} else {
|
|
||||||
entry.key = keyTable[nextIndex];
|
|
||||||
entry.value = map.valueTable[nextIndex];
|
|
||||||
}
|
|
||||||
currentIndex = nextIndex;
|
|
||||||
findNextIndex();
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext () {
|
|
||||||
return hasNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<Entry<V>> iterator () {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static public class Values<V> extends MapIterator<V> implements Iterable<V>, Iterator<V> {
|
|
||||||
public Values (IntMap<V> map) {
|
|
||||||
super(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext () {
|
|
||||||
return hasNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public V next () {
|
|
||||||
if (!hasNext) {
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
throw new RuntimeException("#iterator() cannot be used nested.");
|
|
||||||
}
|
|
||||||
V value;
|
|
||||||
if (nextIndex == INDEX_ZERO) {
|
|
||||||
value = map.zeroValue;
|
|
||||||
} else {
|
|
||||||
value = map.valueTable[nextIndex];
|
|
||||||
}
|
|
||||||
currentIndex = nextIndex;
|
|
||||||
findNextIndex();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<V> iterator () {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a new array containing the remaining values. */
|
|
||||||
// public Array<V> toArray () {
|
|
||||||
// Array array = new Array(true, map.size);
|
|
||||||
// while (hasNext) {
|
|
||||||
// array.add(next());
|
|
||||||
// }
|
|
||||||
// return array;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
static public class Keys extends MapIterator {
|
|
||||||
public Keys (IntMap map) {
|
|
||||||
super(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int next () {
|
|
||||||
if (!hasNext) {
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
throw new RuntimeException("#iterator() cannot be used nested.");
|
|
||||||
}
|
|
||||||
int key = nextIndex == INDEX_ZERO ? 0 : map.keyTable[nextIndex];
|
|
||||||
currentIndex = nextIndex;
|
|
||||||
findNextIndex();
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a new array containing the remaining keys. */
|
|
||||||
public IntArray toArray () {
|
|
||||||
IntArray array = new IntArray(true, map.size);
|
|
||||||
while (hasNext) {
|
|
||||||
array.add(next());
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright 2011 See AUTHORS file.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// pruned/limited version from libGDX
|
|
||||||
|
|
||||||
package dorkbox.network.util.primativeCollections;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class MathUtils {
|
|
||||||
|
|
||||||
// ---
|
|
||||||
|
|
||||||
static public Random random = new Random();
|
|
||||||
|
|
||||||
/** Returns a random number between 0 (inclusive) and the specified value (inclusive). */
|
|
||||||
static public final int random (int range) {
|
|
||||||
return random.nextInt(range + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a random number between start (inclusive) and end (inclusive). */
|
|
||||||
static public final int random (int start, int end) {
|
|
||||||
return start + random.nextInt(end - start + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a random boolean value. */
|
|
||||||
static public final boolean randomBoolean () {
|
|
||||||
return random.nextBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns random number between 0.0 (inclusive) and 1.0 (exclusive). */
|
|
||||||
static public final float random () {
|
|
||||||
return random.nextFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a random number between 0 (inclusive) and the specified value (exclusive). */
|
|
||||||
static public final float random (float range) {
|
|
||||||
return random.nextFloat() * range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a random number between start (inclusive) and end (exclusive). */
|
|
||||||
static public final float random (float start, float end) {
|
|
||||||
return start + random.nextFloat() * (end - start);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next power of two. Returns the specified value if the value
|
|
||||||
* is already a power of two.
|
|
||||||
*/
|
|
||||||
public static int nextPowerOfTwo(int value) {
|
|
||||||
if (value == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value--;
|
|
||||||
|
|
||||||
value |= value >> 1;
|
|
||||||
value |= value >> 2;
|
|
||||||
value |= value >> 4;
|
|
||||||
value |= value >> 8;
|
|
||||||
value |= value >> 16;
|
|
||||||
|
|
||||||
return value + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPowerOfTwo(int value) {
|
|
||||||
return value != 0 && (value & value - 1) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package dorkbox.network.util;
|
package dorkbox.network.util.serializers;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
|
@ -0,0 +1,186 @@
|
||||||
|
package dorkbox.network.util.serializers;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.esotericsoftware.kryo.Kryo;
|
||||||
|
import com.esotericsoftware.kryo.Serializer;
|
||||||
|
import com.esotericsoftware.kryo.factories.SerializerFactory;
|
||||||
|
import com.esotericsoftware.kryo.serializers.FieldSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A kryo {@link FieldSerializer} that allows to exclusively include or exclude fields that
|
||||||
|
* are attributed with user-specific annotations. This can be for example useful when serializing beans that carry
|
||||||
|
* references to a dependency injection framework. As an example for Spring:
|
||||||
|
* <p/>
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* Set<Class<? extends Annotation>> marks = new HashSet<>();
|
||||||
|
* marks.add(Autowired.class);
|
||||||
|
* SerializerFactory disregardingFactory = new FieldAnnotationAwareSerializer.Factory(marks, true);
|
||||||
|
* Kryo kryo = new Kryo();
|
||||||
|
* kryo.setDefaultSerializer(factory);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* <p/>
|
||||||
|
* The resulting {@link Kryo} instance would ignore all fields that are annotated with Spring's {@code @Autowired}
|
||||||
|
* annotation.
|
||||||
|
* <p/>
|
||||||
|
* Similarly, it is possible to created a serializer which does the opposite such that the resulting serializer
|
||||||
|
* would only serialize fields that are annotated with the specified annotations.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:rafael.wth@web.de">Rafael Winterhalter</a>
|
||||||
|
* @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a>
|
||||||
|
*/
|
||||||
|
public class FieldAnnotationAwareSerializer<T> extends FieldSerializer<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for creating instances of {@link FieldAnnotationAwareSerializer}.
|
||||||
|
*/
|
||||||
|
public static class Factory implements SerializerFactory {
|
||||||
|
|
||||||
|
private final Collection<Class<? extends Annotation>> marked;
|
||||||
|
private final boolean disregarding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new factory. See {@link FieldAnnotationAwareSerializer#FieldAnnotationAwareSerializer(
|
||||||
|
*com.esotericsoftware.kryo.Kryo, Class, java.util.Collection, boolean)}
|
||||||
|
* for additional information on the constructor parameters.
|
||||||
|
*
|
||||||
|
* @param marked The annotations that will be considered of the resulting converter.
|
||||||
|
* @param disregarding If {@code true}, the serializer will ignore all annotated fields,
|
||||||
|
* if set to {@code false} it will exclusively look at annotated fields.
|
||||||
|
*/
|
||||||
|
public Factory(final Collection<Class<? extends Annotation>> marked, final boolean disregarding) {
|
||||||
|
this.marked = marked;
|
||||||
|
this.disregarding = disregarding;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializer<?> makeSerializer(final Kryo kryo, final Class<?> type) {
|
||||||
|
return new FieldAnnotationAwareSerializer<Object>(kryo, type, this.marked, this.disregarding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Set<Class<? extends Annotation>> marked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether annotated fields should be excluded from serialization.
|
||||||
|
* <p/>
|
||||||
|
* {@code true} if annotated fields should be excluded from serialization,
|
||||||
|
* {@code false} if only annotated fields should be included from serialization.
|
||||||
|
*/
|
||||||
|
private final boolean disregarding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new field annotation aware serializer.
|
||||||
|
*
|
||||||
|
* @param kryo The {@link Kryo} instace.
|
||||||
|
* @param type The type of the class being serialized.
|
||||||
|
* @param marked The annotations this serializer considers for its serialization process. Be aware tha
|
||||||
|
* a serializer with {@code disregarding} set to {@code false} will never be able to
|
||||||
|
* serialize fields that are not annotated with any of these annotations since it is not
|
||||||
|
* possible to add fields to a {@link FieldSerializer} once it is created. See the
|
||||||
|
* documentation to {@link FieldAnnotationAwareSerializer#addAnnotation(Class)} and
|
||||||
|
* {@link FieldAnnotationAwareSerializer#removeAnnotation(Class)} for further information.
|
||||||
|
* @param disregarding If {@code true}, the serializer will ignore all annotated fields,
|
||||||
|
* if set to {@code false} it will exclusively look at annotated fields.
|
||||||
|
*/
|
||||||
|
public FieldAnnotationAwareSerializer(final Kryo kryo,
|
||||||
|
final Class<?> type,
|
||||||
|
final Collection<Class<? extends Annotation>> marked,
|
||||||
|
final boolean disregarding) {
|
||||||
|
super(kryo, type);
|
||||||
|
this.disregarding = disregarding;
|
||||||
|
this.marked = new HashSet<Class<? extends Annotation>>(marked);
|
||||||
|
rebuildCachedFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void rebuildCachedFields() {
|
||||||
|
// In order to avoid rebuilding the cached fields twice, the super constructor's call
|
||||||
|
// to this method will be suppressed. This can be done by a simple check of the initialization
|
||||||
|
// state of a property of this subclass.
|
||||||
|
if (this.marked == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.rebuildCachedFields();
|
||||||
|
removeFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFields() {
|
||||||
|
final CachedField<?>[] cachedFields = getFields();
|
||||||
|
for (final CachedField<?> cachedField : cachedFields) {
|
||||||
|
final Field field = cachedField.getField();
|
||||||
|
if (isRemove(field)) {
|
||||||
|
// if (TRACE) {
|
||||||
|
// trace("kryo", String.format("Ignoring field %s tag: %s", this.disregarding ? "without" : "with", cachedField));
|
||||||
|
// }
|
||||||
|
super.removeField(field.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRemove(final Field field) {
|
||||||
|
return !isMarked(field) ^ this.disregarding;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMarked(final Field field) {
|
||||||
|
for (final Annotation annotation : field.getAnnotations()) {
|
||||||
|
final Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||||
|
if (this.marked.contains(annotationType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an annotation to the annotations that are considered by this serializer.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important</b>: This will not have an effect if the serializer was configured
|
||||||
|
* to exclusively serialize annotated fields by setting {@code disregarding} to
|
||||||
|
* {@code false}. This is similar to the contract of this serializer's superclass
|
||||||
|
* {@link FieldSerializer} which does not allow to add fields that were formerly
|
||||||
|
* removed. If this was possible, instances that were serialized before this field
|
||||||
|
* was added could not longer be properly deserialized. In order to make this contract
|
||||||
|
* break explicit, you need to create a new instance of this serializer if you want to
|
||||||
|
* include new fields to a serializer that exclusively serializes annotated fields.
|
||||||
|
*
|
||||||
|
* @param clazz The annotation class to be added.
|
||||||
|
* @return {@code true} if the method call had an effect.
|
||||||
|
*/
|
||||||
|
public boolean addAnnotation(final Class<? extends Annotation> clazz) {
|
||||||
|
if (this.disregarding && this.marked.add(clazz)) {
|
||||||
|
initializeCachedFields();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an annotation to the annotations that are considered by this serializer.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important</b>: This will not have an effect if the serializer was configured
|
||||||
|
* to not serialize annotated fields by setting {@code disregarding} to
|
||||||
|
* {@code true}. This is similar to the contract of this serializer's superclass
|
||||||
|
* {@link FieldSerializer} which does not allow to add fields that were formerly
|
||||||
|
* removed. If this was possible, instances that were serialized before this field
|
||||||
|
* was added could not longer be properly deserialized. In order to make this contract
|
||||||
|
* break explicit, you need to create a new instance of this serializer if you want to
|
||||||
|
* include new fields to a serializer that ignores annotated fields for serialization.
|
||||||
|
*
|
||||||
|
* @param clazz The annotation class to be removed.
|
||||||
|
* @return {@code true} if the method call had an effect.
|
||||||
|
*/
|
||||||
|
public boolean removeAnnotation(final Class<? extends Annotation> clazz) {
|
||||||
|
if (!this.disregarding && this.marked.remove(clazz)) {
|
||||||
|
initializeCachedFields();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package dorkbox.network.util;
|
package dorkbox.network.util.serializers;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
|
@ -6,7 +6,7 @@ import java.security.SecureRandom;
|
||||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||||
|
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class NullSettingsStore extends SettingsStore {
|
public class NullSettingsStore extends SettingsStore {
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.util.Storage;
|
import dorkbox.util.Storage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,9 +18,9 @@ import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
import ch.qos.logback.core.ConsoleAppender;
|
import ch.qos.logback.core.ConsoleAppender;
|
||||||
import dorkbox.network.connection.EndPoint;
|
import dorkbox.network.connection.EndPoint;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.entropy.Entropy;
|
import dorkbox.network.util.entropy.Entropy;
|
||||||
import dorkbox.network.util.entropy.SimpleEntropy;
|
import dorkbox.network.util.entropy.SimpleEntropy;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
|
||||||
public abstract class BaseTest {
|
public abstract class BaseTest {
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class BufferTest extends BaseTest {
|
public class BufferTest extends BaseTest {
|
||||||
private static final int OBJ_SIZE = 1024 * 10;
|
private static final int OBJ_SIZE = 1024 * 10;
|
||||||
|
|
|
@ -11,9 +11,9 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class ClientSendTest extends BaseTest {
|
public class ClientSendTest extends BaseTest {
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class ConnectionTest extends BaseTest {
|
public class ConnectionTest extends BaseTest {
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class DiscoverHostTest extends BaseTest {
|
public class DiscoverHostTest extends BaseTest {
|
||||||
volatile boolean connected = false;
|
volatile boolean connected = false;
|
||||||
|
|
|
@ -16,9 +16,9 @@ import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.connection.idle.IdleBridge;
|
import dorkbox.network.connection.idle.IdleBridge;
|
||||||
import dorkbox.network.connection.idle.InputStreamSender;
|
import dorkbox.network.connection.idle.InputStreamSender;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes"})
|
@SuppressWarnings({"rawtypes"})
|
||||||
public class IdleTest extends BaseTest {
|
public class IdleTest extends BaseTest {
|
||||||
|
|
|
@ -15,8 +15,8 @@ import org.junit.Test;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.ConnectionImpl;
|
import dorkbox.network.connection.ConnectionImpl;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class ListenerTest extends BaseTest {
|
public class ListenerTest extends BaseTest {
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class MultipleServerTest extends BaseTest {
|
public class MultipleServerTest extends BaseTest {
|
||||||
AtomicInteger received = new AtomicInteger();
|
AtomicInteger received = new AtomicInteger();
|
||||||
|
|
|
@ -15,8 +15,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class MultipleThreadTest extends BaseTest {
|
public class MultipleThreadTest extends BaseTest {
|
||||||
AtomicInteger sent = new AtomicInteger(0);
|
AtomicInteger sent = new AtomicInteger(0);
|
||||||
|
|
|
@ -11,9 +11,9 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class PingPongLocalTest extends BaseTest {
|
public class PingPongLocalTest extends BaseTest {
|
||||||
private volatile String fail;
|
private volatile String fail;
|
||||||
|
|
|
@ -14,9 +14,9 @@ import org.junit.Test;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.EndPoint;
|
import dorkbox.network.connection.EndPoint;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class PingPongTest extends BaseTest {
|
public class PingPongTest extends BaseTest {
|
||||||
private volatile String fail;
|
private volatile String fail;
|
||||||
|
|
|
@ -11,8 +11,8 @@ import org.junit.Test;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.connection.ping.PingMessage;
|
import dorkbox.network.connection.ping.PingMessage;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
|
|
||||||
public class PingTest extends BaseTest {
|
public class PingTest extends BaseTest {
|
||||||
|
|
|
@ -13,8 +13,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class ReconnectTest extends BaseTest {
|
public class ReconnectTest extends BaseTest {
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
import dorkbox.network.util.store.SettingsStore;
|
import dorkbox.network.util.store.SettingsStore;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class ReuseTest extends BaseTest {
|
public class ReuseTest extends BaseTest {
|
||||||
AtomicInteger serverCount;
|
AtomicInteger serverCount;
|
||||||
|
|
|
@ -14,8 +14,8 @@ import org.junit.Test;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.EndPoint;
|
import dorkbox.network.connection.EndPoint;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
import dorkbox.network.util.SecurityException;
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class UnregisteredClassTest extends BaseTest {
|
public class UnregisteredClassTest extends BaseTest {
|
||||||
private String fail;
|
private String fail;
|
||||||
|
|
|
@ -13,9 +13,9 @@ import dorkbox.network.BaseTest;
|
||||||
import dorkbox.network.Server;
|
import dorkbox.network.Server;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class RmiSendObjectTest extends BaseTest {
|
public class RmiSendObjectTest extends BaseTest {
|
||||||
private RmiBridge serverRMI;
|
private RmiBridge serverRMI;
|
||||||
|
|
|
@ -15,9 +15,9 @@ import dorkbox.network.BaseTest;
|
||||||
import dorkbox.network.Server;
|
import dorkbox.network.Server;
|
||||||
import dorkbox.network.connection.Connection;
|
import dorkbox.network.connection.Connection;
|
||||||
import dorkbox.network.connection.Listener;
|
import dorkbox.network.connection.Listener;
|
||||||
import dorkbox.network.util.InitializationException;
|
|
||||||
import dorkbox.network.util.SecurityException;
|
|
||||||
import dorkbox.network.util.SerializationManager;
|
import dorkbox.network.util.SerializationManager;
|
||||||
|
import dorkbox.network.util.exceptions.InitializationException;
|
||||||
|
import dorkbox.network.util.exceptions.SecurityException;
|
||||||
|
|
||||||
public class RmiTest extends BaseTest {
|
public class RmiTest extends BaseTest {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue