From 1d12f2dbcd2cf0e4922e0ab90bb026ec4f667e44 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 28 Jul 2015 02:23:01 +0200 Subject: [PATCH] RMI method override implemented. lots of misc fixes --- Dorkbox-Util/src/dorkbox/util/Message.java | 4 +- .../dorkbox/util/SerializationManager.java | 22 ++++-- .../src/dorkbox/util/database/DB_Server.java | 2 +- .../dorkbox/util/exceptions/NetException.java | 42 ----------- .../UnmodifiableCollectionsSerializer.java | 3 +- .../src/dorkbox/util/storage/DiskStorage.java | 71 +++++++++++++------ .../dorkbox/util/storage/MemoryStorage.java | 37 ++++++---- .../src/dorkbox/util/storage/Metadata.java | 6 +- .../src/dorkbox/util/storage/Storage.java | 28 +++++--- .../src/dorkbox/util/storage/StorageBase.java | 6 +- .../src/dorkbox/util/storage/Store.java | 2 +- .../test/dorkbox/util/StorageTest.java | 28 +++++--- 12 files changed, 138 insertions(+), 113 deletions(-) delete mode 100644 Dorkbox-Util/src/dorkbox/util/exceptions/NetException.java diff --git a/Dorkbox-Util/src/dorkbox/util/Message.java b/Dorkbox-Util/src/dorkbox/util/Message.java index 5d13488..080c937 100644 --- a/Dorkbox-Util/src/dorkbox/util/Message.java +++ b/Dorkbox-Util/src/dorkbox/util/Message.java @@ -15,8 +15,6 @@ */ package dorkbox.util; -import java.io.Serializable; - -public interface Message extends Serializable { +public interface Message { } diff --git a/Dorkbox-Util/src/dorkbox/util/SerializationManager.java b/Dorkbox-Util/src/dorkbox/util/SerializationManager.java index 70ed68a..e44e757 100644 --- a/Dorkbox-Util/src/dorkbox/util/SerializationManager.java +++ b/Dorkbox-Util/src/dorkbox/util/SerializationManager.java @@ -21,6 +21,9 @@ import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import io.netty.buffer.ByteBuf; +import org.slf4j.Logger; + +import java.io.IOException; public interface SerializationManager { @@ -72,7 +75,7 @@ interface SerializationManager { *

* There is a small speed penalty if there were no kryo's available to use. */ - void write(ByteBuf buffer, Object message); + void write(ByteBuf buffer, Object message) throws IOException; /** * Reads an object from the buffer. @@ -81,17 +84,17 @@ interface SerializationManager { * * @param length should ALWAYS be the length of the expected object! */ - Object read(ByteBuf buffer, int length); + Object read(ByteBuf buffer, int length) throws IOException; /** * Writes the class and object using an available kryo instance */ - void writeFullClassAndObject(Output output, Object value); + void writeFullClassAndObject(final Logger logger, Output output, Object value) throws IOException; /** * Returns a class read from the input */ - Object readFullClassAndObject(Input input); + Object readFullClassAndObject(final Logger logger, final Input input) throws IOException; /** * Borrows a kryo from the threadsafe pool. You must release it back to the pool when done. @@ -102,4 +105,15 @@ interface SerializationManager { * Releases the kryo back to the threadsafe pool */ void release(Kryo kryo); + + /** + * Called when initialization is complete. This is to prevent (and recognize) out-of-order class/serializer registration. + */ + void finishInit(); + + /** + * @return true if our initialization is complete. Some registrations (in the property store, for example) always register for client + * and server, even if in the same JVM. This only attempts to register once. + */ + boolean initialized(); } diff --git a/Dorkbox-Util/src/dorkbox/util/database/DB_Server.java b/Dorkbox-Util/src/dorkbox/util/database/DB_Server.java index 73466f4..3e83339 100644 --- a/Dorkbox-Util/src/dorkbox/util/database/DB_Server.java +++ b/Dorkbox-Util/src/dorkbox/util/database/DB_Server.java @@ -26,7 +26,7 @@ class DB_Server { /** * Address 0.0.0.0/32 may be used as a source address for this host on this network. */ - public static final ByteArrayWrapper IP_0_0_0_0 = ByteArrayWrapper.wrap(new byte[] {0, 0, 0, 0}); + public static final ByteArrayWrapper IP_LOCALHOST = ByteArrayWrapper.wrap(new byte[] {127, 0, 0, 1}); // salt + IP address is used for equals! private byte[] ipAddress; diff --git a/Dorkbox-Util/src/dorkbox/util/exceptions/NetException.java b/Dorkbox-Util/src/dorkbox/util/exceptions/NetException.java deleted file mode 100644 index 00b7d1c..0000000 --- a/Dorkbox-Util/src/dorkbox/util/exceptions/NetException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util.exceptions; - -public -class NetException extends RuntimeException { - - private static final long serialVersionUID = -3499720814336253695L; - - public - NetException() { - super(); - } - - public - NetException(String message, Throwable cause) { - super(message, cause); - } - - public - NetException(String message) { - super(message); - } - - public - NetException(Throwable cause) { - super(cause); - } -} diff --git a/Dorkbox-Util/src/dorkbox/util/serialization/UnmodifiableCollectionsSerializer.java b/Dorkbox-Util/src/dorkbox/util/serialization/UnmodifiableCollectionsSerializer.java index 84b1580..12b1b1e 100644 --- a/Dorkbox-Util/src/dorkbox/util/serialization/UnmodifiableCollectionsSerializer.java +++ b/Dorkbox-Util/src/dorkbox/util/serialization/UnmodifiableCollectionsSerializer.java @@ -20,7 +20,6 @@ import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; -import dorkbox.util.exceptions.NetException; import dorkbox.util.SerializationManager; import java.lang.reflect.Field; @@ -48,7 +47,7 @@ public class UnmodifiableCollectionsSerializer extends Serializer { .getDeclaredField("m"); SOURCE_MAP_FIELD.setAccessible( true ); } catch ( final Exception e ) { - throw new NetException("Could not access source collection" + + throw new RuntimeException("Could not access source collection" + " field in java.util.Collections$UnmodifiableCollection.", e ); } } diff --git a/Dorkbox-Util/src/dorkbox/util/storage/DiskStorage.java b/Dorkbox-Util/src/dorkbox/util/storage/DiskStorage.java index 1ca211e..b26f03c 100644 --- a/Dorkbox-Util/src/dorkbox/util/storage/DiskStorage.java +++ b/Dorkbox-Util/src/dorkbox/util/storage/DiskStorage.java @@ -159,7 +159,7 @@ class DiskStorage implements Storage { } /** - * Uses the DEFAULT key ("") to return saved data. + * Uses the DEFAULT key ("") to return saved data. Also saves the data. *

* This will check to see if there is an associated key for that data, if not - it will use data as the default * @@ -167,48 +167,48 @@ class DiskStorage implements Storage { */ @Override public - T load(T data) throws IOException { - return load(this.defaultKey, data); + T getAndPut(T data) throws IOException { + return getAndPut(this.defaultKey, data); } /** - * Returns the saved data for the specified key. + * Returns the saved data for the specified key. Also saves the data. * * @param data If there is no object in the DB with the specified key, this value will be the default (and will be saved to the db) */ @Override public - T load(String key, T data) throws IOException { + T getAndPut(String key, T data) throws IOException { ByteArrayWrapper wrap = ByteArrayWrapper.wrap(key); - return load(wrap, data); + return getAndPut(wrap, data); } /** - * Returns the saved data for the specified key. + * Returns the saved data for the specified key. Also saves the data. * * @param data If there is no object in the DB with the specified key, this value will be the default (and will be saved to the db) */ @Override public - T load(byte[] key, T data) throws IOException { - return load(ByteArrayWrapper.wrap(key), data); + T getAndPut(byte[] key, T data) throws IOException { + return getAndPut(ByteArrayWrapper.wrap(key), data); } /** - * Returns the saved data for the specified key. + * Returns the saved data for the specified key. Also saves the data. * * @param data If there is no object in the DB with the specified key, this value will be the default (and will be saved to the db) */ @Override @SuppressWarnings("unchecked") public - T load(ByteArrayWrapper key, T data) throws IOException { + T getAndPut(ByteArrayWrapper key, T data) throws IOException { Object source = get0(key); if (source == null) { // returned was null, so we should take value as the default - put(key, data); + putAndSave(key, data); return data; } else { @@ -318,7 +318,7 @@ class DiskStorage implements Storage { } /** - * Deletes an object from storage. To ALSO remove from the cache, use unRegister(key) + * Deletes an object from storage. * * @return true if the delete was successful. False if there were problems deleting the data. */ @@ -341,6 +341,28 @@ class DiskStorage implements Storage { } } + /** + * Deletes an object from storage. + * + * @return true if the delete was successful. False if there were problems deleting the data. + */ + @Override + public final + boolean delete(ByteArrayWrapper key) { + if (!this.isOpen.get()) { + throw new RuntimeException("Unable to act on closed storage"); + } + + // timer action runs on THIS thread, not timer thread + if (timer != null) { + this.timer.delay(0L); + return this.storage.delete(key); + } + else { + return false; + } + } + /** * Closes the database and file. */ @@ -352,10 +374,7 @@ class DiskStorage implements Storage { // have to "close" it after we run the timer! this.isOpen.set(false); - - if (timer != null) { - this.storage.close(); - } + this.storage.close(); } /** @@ -446,8 +465,14 @@ class DiskStorage implements Storage { try { this.actionLock.lock(); - // push action to map - this.actionMap.put(key, object); + if (object != null) { + // push action to map + this.actionMap.put(key, object); + } else { + this.actionMap.remove(key); + } + + } finally { this.actionLock.unlock(); } @@ -477,7 +502,7 @@ class DiskStorage implements Storage { */ @Override public final - void commit() { + void save() { if (!this.isOpen.get()) { throw new RuntimeException("Unable to act on closed storage"); } @@ -495,7 +520,7 @@ class DiskStorage implements Storage { */ @Override public - void commit(final String key, final Object object) { + void putAndSave(final String key, final Object object) { if (!this.isOpen.get()) { throw new RuntimeException("Unable to act on closed storage"); } @@ -514,7 +539,7 @@ class DiskStorage implements Storage { */ @Override public - void commit(final byte[] key, final Object object) { + void putAndSave(final byte[] key, final Object object) { if (!this.isOpen.get()) { throw new RuntimeException("Unable to act on closed storage"); } @@ -535,7 +560,7 @@ class DiskStorage implements Storage { */ @Override public - void commit(final ByteArrayWrapper key, final Object object) { + void putAndSave(final ByteArrayWrapper key, final Object object) { if (!this.isOpen.get()) { throw new RuntimeException("Unable to act on closed storage"); } diff --git a/Dorkbox-Util/src/dorkbox/util/storage/MemoryStorage.java b/Dorkbox-Util/src/dorkbox/util/storage/MemoryStorage.java index cdbe572..1d7459b 100644 --- a/Dorkbox-Util/src/dorkbox/util/storage/MemoryStorage.java +++ b/Dorkbox-Util/src/dorkbox/util/storage/MemoryStorage.java @@ -103,8 +103,8 @@ class MemoryStorage implements Storage { */ @Override public - T load(T data) throws IOException { - return load(this.defaultKey, data); + T getAndPut(T data) throws IOException { + return getAndPut(this.defaultKey, data); } /** @@ -114,10 +114,10 @@ class MemoryStorage implements Storage { */ @Override public - T load(String key, T data) throws IOException { + T getAndPut(String key, T data) throws IOException { ByteArrayWrapper wrap = ByteArrayWrapper.wrap(key); - return load(wrap, data); + return getAndPut(wrap, data); } /** @@ -127,14 +127,14 @@ class MemoryStorage implements Storage { */ @Override public - T load(byte[] key, T data) throws IOException { - return load(ByteArrayWrapper.wrap(key), data); + T getAndPut(byte[] key, T data) throws IOException { + return getAndPut(ByteArrayWrapper.wrap(key), data); } @SuppressWarnings("unchecked") @Override public - T load(final ByteArrayWrapper key, final T data) throws IOException { + T getAndPut(final ByteArrayWrapper key, final T data) throws IOException { final Object o = storage.get(key); if (o == null) { storage.put(key, data); @@ -192,14 +192,25 @@ class MemoryStorage implements Storage { } /** - * Deletes an object from storage. To ALSO remove from the cache, use unRegister(key) + * Deletes an object from storage. * * @return true if the delete was successful. False if there were problems deleting the data. */ @Override public boolean delete(final String key) { - storage.remove(ByteArrayWrapper.wrap(key)); + return delete(ByteArrayWrapper.wrap(key)); + } + + /** + * Deletes an object from storage. + * + * @return true if the delete was successful. False if there were problems deleting the data. + */ + @Override + public + boolean delete(final ByteArrayWrapper key) { + storage.remove(key); return true; } @@ -246,25 +257,25 @@ class MemoryStorage implements Storage { @Override public - void commit() { + void save() { // no-op } @Override public - void commit(final String key, final Object object) { + void putAndSave(final String key, final Object object) { // no-op } @Override public - void commit(final byte[] key, final Object object) { + void putAndSave(final byte[] key, final Object object) { // no-op } @Override public - void commit(final ByteArrayWrapper key, final Object object) { + void putAndSave(final ByteArrayWrapper key, final Object object) { // no-op } } diff --git a/Dorkbox-Util/src/dorkbox/util/storage/Metadata.java b/Dorkbox-Util/src/dorkbox/util/storage/Metadata.java index 7bc2bd7..8be7996 100644 --- a/Dorkbox-Util/src/dorkbox/util/storage/Metadata.java +++ b/Dorkbox-Util/src/dorkbox/util/storage/Metadata.java @@ -260,10 +260,10 @@ class Metadata { */ static - T readData(SerializationManager serializationManager, InflaterInputStream inputStream) { + T readData(SerializationManager serializationManager, InflaterInputStream inputStream) throws IOException { Input input = new Input(inputStream, 1024); // read 1024 at a time @SuppressWarnings("unchecked") - T readObject = (T) serializationManager.readFullClassAndObject(input); + T readObject = (T) serializationManager.readFullClassAndObject(null, input); return readObject; } @@ -277,7 +277,7 @@ class Metadata { final DeflaterOutputStream outputStream) throws IOException { // HAVE TO LOCK BEFORE THIS IS CALLED! (AND FREE AFTERWARDS!) Output output = new Output(outputStream, 1024); // write 1024 at a time - serializationManager.writeFullClassAndObject(output, data); + serializationManager.writeFullClassAndObject(null, output, data); output.flush(); outputStream.flush(); // sync-flush is enabled, so the output stream will finish compressing data. diff --git a/Dorkbox-Util/src/dorkbox/util/storage/Storage.java b/Dorkbox-Util/src/dorkbox/util/storage/Storage.java index ea9967f..98138eb 100644 --- a/Dorkbox-Util/src/dorkbox/util/storage/Storage.java +++ b/Dorkbox-Util/src/dorkbox/util/storage/Storage.java @@ -23,6 +23,7 @@ import java.io.IOException; /** * */ +@SuppressWarnings("unused") public interface Storage { /** @@ -36,7 +37,7 @@ interface Storage { boolean contains(String key); /** - * Reads a object using the default (blank) key, and casts it to the expected class + * Reads a object using the DEFAULT key ("") key, and casts it to the expected class */ T get(); @@ -62,21 +63,21 @@ interface Storage { * * @param data The data that will hold the copy of the data from disk */ - T load(T data) throws IOException; + T getAndPut(T data) throws IOException; /** * Returns the saved data for the specified key. * * @param data If there is no object in the DB with the specified key, this value will be the default (and will be saved to the db) */ - T load(String key, T data) throws IOException; + T getAndPut(String key, T data) throws IOException; /** * Returns the saved data for the specified key. * * @param data If there is no object in the DB with the specified key, this value will be the default (and will be saved to the db) */ - T load(byte[] key, T data) throws IOException; + T getAndPut(byte[] key, T data) throws IOException; /** * Returns the saved data for the specified key. @@ -84,7 +85,7 @@ interface Storage { * @param data If there is no object in the DB with the specified key, this value will be the default (and will be saved to the db) */ @SuppressWarnings("unchecked") - T load(ByteArrayWrapper key, T data) throws IOException; + T getAndPut(ByteArrayWrapper key, T data) throws IOException; /** * Saves the given data to storage with the associated key. @@ -119,12 +120,19 @@ interface Storage { void put(Object data); /** - * Deletes an object from storage. To ALSO remove from the cache, use unRegister(key) + * Deletes an object from storage. * * @return true if the delete was successful. False if there were problems deleting the data. */ boolean delete(String key); + /** + * Deletes an object from storage. + * + * @return true if the delete was successful. False if there were problems deleting the data. + */ + boolean delete(ByteArrayWrapper key); + /** * @return the file that backs this storage */ @@ -167,26 +175,26 @@ interface Storage { *

* This will save the ALL of the pending save actions to the file */ - void commit(); + void save(); /** * Save the storage to disk, immediately. *

* This will save the ALL of the pending save actions to the file */ - void commit(String key, Object object); + void putAndSave(String key, Object object); /** * Save the storage to disk, immediately. *

* This will save the ALL of the pending save actions to the file */ - void commit(byte[] key, Object object); + void putAndSave(byte[] key, Object object); /** * Save the storage to disk, immediately. *

* This will save the ALL of the pending save actions to the file */ - void commit(ByteArrayWrapper key, Object object); + void putAndSave(ByteArrayWrapper key, Object object); } diff --git a/Dorkbox-Util/src/dorkbox/util/storage/StorageBase.java b/Dorkbox-Util/src/dorkbox/util/storage/StorageBase.java index 3eaee71..2a75ade 100644 --- a/Dorkbox-Util/src/dorkbox/util/storage/StorageBase.java +++ b/Dorkbox-Util/src/dorkbox/util/storage/StorageBase.java @@ -379,7 +379,7 @@ class StorageBase { } else { // this is comparatively slow, since we serialize it first to get the size, then we put it in the file. - ByteArrayOutputStream dataStream = getDataAsByteArray(this.serializationManager, object, deflater); + ByteArrayOutputStream dataStream = getDataAsByteArray(this.serializationManager, this.logger, object, deflater); int size = dataStream.size(); if (size > metaData.dataCapacity) { @@ -445,11 +445,11 @@ class StorageBase { private static - ByteArrayOutputStream getDataAsByteArray(SerializationManager kryo, Object data, Deflater deflater) throws IOException { + ByteArrayOutputStream getDataAsByteArray(SerializationManager serializationManager, Logger logger, Object data, Deflater deflater) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); OutputStream outputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater); Output output = new Output(outputStream, 1024); // write 1024 at a time - kryo.writeFullClassAndObject(output, data); + serializationManager.writeFullClassAndObject(logger, output, data); output.flush(); outputStream.flush(); diff --git a/Dorkbox-Util/src/dorkbox/util/storage/Store.java b/Dorkbox-Util/src/dorkbox/util/storage/Store.java index aaec363..157a163 100644 --- a/Dorkbox-Util/src/dorkbox/util/storage/Store.java +++ b/Dorkbox-Util/src/dorkbox/util/storage/Store.java @@ -151,7 +151,7 @@ class Store { boolean waiting = storage.hasWriteWaiting(); // we want this storage to be in a fresh state if (waiting) { - storage.commit(); + storage.save(); } ((DiskStorage) storage).increaseReference(); } diff --git a/Dorkbox-Util/test/dorkbox/util/StorageTest.java b/Dorkbox-Util/test/dorkbox/util/StorageTest.java index efe600f..75fdecb 100644 --- a/Dorkbox-Util/test/dorkbox/util/StorageTest.java +++ b/Dorkbox-Util/test/dorkbox/util/StorageTest.java @@ -9,6 +9,7 @@ import dorkbox.util.storage.Store; import io.netty.buffer.ByteBuf; import org.junit.*; import org.junit.runners.MethodSorters; +import org.slf4j.Logger; import java.io.File; import java.io.IOException; @@ -44,17 +45,17 @@ class StorageTest { public void write(final ByteBuf buffer, final Object message) { final Output output = new Output(); - writeFullClassAndObject(output, message); + writeFullClassAndObject(null, output, message); buffer.writeBytes(output.getBuffer()); } @Override public - Object read(final ByteBuf buffer, final int length) { + Object read(final ByteBuf buffer, final int length) throws IOException { final Input input = new Input(); buffer.readBytes(input.getBuffer()); - final Object o = readFullClassAndObject(input); + final Object o = readFullClassAndObject(null, input); buffer.skipBytes(input.position()); return o; @@ -62,13 +63,13 @@ class StorageTest { @Override public - void writeFullClassAndObject(final Output output, final Object value) { + void writeFullClassAndObject(final Logger logger, final Output output, final Object value) { kryo.writeClassAndObject(output, value); } @Override public - Object readFullClassAndObject(final Input input) { + Object readFullClassAndObject(final Logger logger, final Input input) throws IOException { return kryo.readClassAndObject(input); } @@ -82,6 +83,17 @@ class StorageTest { public void release(final Kryo kryo) { } + + @Override + public + void finishInit() { + } + + @Override + public + boolean initialized() { + return false; + } }; static @@ -335,7 +347,7 @@ class StorageTest { storage.put(createKey, data); Data data2 = new Data(); - storage.load(createKey, data2); + storage.getAndPut(createKey, data2); Assert.assertEquals("Object is not the same", data, data2); Store.close(storage); @@ -345,7 +357,7 @@ class StorageTest { .make(); data2 = new Data(); - storage.load(createKey, data2); + storage.getAndPut(createKey, data2); Assert.assertEquals("Object is not the same", data, data2); Store.close(storage); @@ -522,7 +534,7 @@ class StorageTest { String createKey = createKey(i); Data data2 = new Data(); - storage.load(createKey, data2); + storage.getAndPut(createKey, data2); Assert.assertEquals("Object is not the same", data, data2); } Store.close(storage);