diff --git a/src/main/java/de/hhu/bsinfo/dxmem/DXMem.java b/src/main/java/de/hhu/bsinfo/dxmem/DXMem.java index 67fa257..ca03580 100644 --- a/src/main/java/de/hhu/bsinfo/dxmem/DXMem.java +++ b/src/main/java/de/hhu/bsinfo/dxmem/DXMem.java @@ -18,29 +18,12 @@ import java.io.File; +import de.hhu.bsinfo.dxmem.operations.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import de.hhu.bsinfo.dxmem.core.Context; import de.hhu.bsinfo.dxmem.core.MemoryRuntimeException; -import de.hhu.bsinfo.dxmem.operations.Analyze; -import de.hhu.bsinfo.dxmem.operations.CIDStatus; -import de.hhu.bsinfo.dxmem.operations.Create; -import de.hhu.bsinfo.dxmem.operations.CreateReserved; -import de.hhu.bsinfo.dxmem.operations.Dump; -import de.hhu.bsinfo.dxmem.operations.Exists; -import de.hhu.bsinfo.dxmem.operations.Get; -import de.hhu.bsinfo.dxmem.operations.Lock; -import de.hhu.bsinfo.dxmem.operations.Pinning; -import de.hhu.bsinfo.dxmem.operations.Put; -import de.hhu.bsinfo.dxmem.operations.RawRead; -import de.hhu.bsinfo.dxmem.operations.RawWrite; -import de.hhu.bsinfo.dxmem.operations.Recovery; -import de.hhu.bsinfo.dxmem.operations.Remove; -import de.hhu.bsinfo.dxmem.operations.Reserve; -import de.hhu.bsinfo.dxmem.operations.Resize; -import de.hhu.bsinfo.dxmem.operations.Size; -import de.hhu.bsinfo.dxmem.operations.Stats; import de.hhu.bsinfo.dxmonitor.state.MemState; import de.hhu.bsinfo.dxmonitor.state.StateUpdateException; import de.hhu.bsinfo.dxutils.unit.StorageUnit; @@ -69,6 +52,7 @@ public class DXMem { private Pinning m_pinning; private RawRead m_rawRead; private RawWrite m_rawWrite; + private RawCompare m_rawCompare; private CIDStatus m_cidStatus; private Stats m_stats; @@ -82,8 +66,7 @@ public class DXMem { * Constructor * Load a memory dump from a file and initialize DXMem with it. * - * @param p_memdumpFile - * Path to memory dump file + * @param p_memdumpFile Path to memory dump file */ public DXMem(final String p_memdumpFile) { this(p_memdumpFile, false); @@ -93,14 +76,12 @@ public DXMem(final String p_memdumpFile) { * Constructor * Load a memory dump from a file and initialize DXMem with it. * - * @param p_memdumpFile - * Path to memory dump file - * @param p_disableChunkLock - * Disable the chunk lock mechanism which increases performance but blocks the remove - * and resize operations. All lock operation arguments provided on operation calls are - * ignored. DXMem cannot guarantee application data consistency on parallel writes to - * the same chunk. Useful for read only applications or if the application handles - * synchronization when writing to chunks. + * @param p_memdumpFile Path to memory dump file + * @param p_disableChunkLock Disable the chunk lock mechanism which increases performance but blocks the remove + * and resize operations. All lock operation arguments provided on operation calls are + * ignored. DXMem cannot guarantee application data consistency on parallel writes to + * the same chunk. Useful for read only applications or if the application handles + * synchronization when writing to chunks. */ public DXMem(final String p_memdumpFile, final boolean p_disableChunkLock) { checkSufficientMemory(new StorageUnit(new File(p_memdumpFile).length(), StorageUnit.BYTE)); @@ -118,10 +99,8 @@ public DXMem(final String p_memdumpFile, final boolean p_disableChunkLock) { * Constructor * Create a new empty heap and initialize DXMem. * - * @param p_nodeId - * Node id of current instance - * @param p_heapSize - * Size of heap to create (in bytes) + * @param p_nodeId Node id of current instance + * @param p_heapSize Size of heap to create (in bytes) */ public DXMem(final short p_nodeId, final long p_heapSize) { this(p_nodeId, p_heapSize, false); @@ -131,16 +110,13 @@ public DXMem(final short p_nodeId, final long p_heapSize) { * Constructor * Create a new empty heap and initialize DXMem. * - * @param p_nodeId - * Node id of current instance - * @param p_heapSize - * Size of heap to create (in bytes) - * @param p_disableChunkLock - * Disable the chunk lock mechanism which increases performance but blocks the remove - * and resize operations. All lock operation arguments provided on operation calls are - * ignored. DXMem cannot guarantee application data consistency on parallel writes to - * the same chunk. Useful for read only applications or if the application handles - * synchronization when writing to chunks. + * @param p_nodeId Node id of current instance + * @param p_heapSize Size of heap to create (in bytes) + * @param p_disableChunkLock Disable the chunk lock mechanism which increases performance but blocks the remove + * and resize operations. All lock operation arguments provided on operation calls are + * ignored. DXMem cannot guarantee application data consistency on parallel writes to + * the same chunk. Useful for read only applications or if the application handles + * synchronization when writing to chunks. */ public DXMem(final short p_nodeId, final long p_heapSize, final boolean p_disableChunkLock) { checkSufficientMemory(new StorageUnit(p_heapSize, StorageUnit.BYTE)); @@ -292,6 +268,15 @@ public RawWrite rawWrite() { return m_rawWrite; } + /** + * Return the rawCompare Operation. + * + * @return the rawCompare Operation. + */ + public RawCompare rawCompare() { + return m_rawCompare; + } + /** * Get the cidStatus operation * @@ -355,6 +340,7 @@ private void initOperations() { m_pinning = new Pinning(m_context); m_rawRead = new RawRead(m_context); m_rawWrite = new RawWrite(m_context); + m_rawCompare = new RawCompare(m_context); m_cidStatus = new CIDStatus(m_context); m_stats = new Stats(m_context); diff --git a/src/main/java/de/hhu/bsinfo/dxmem/data/ChunkState.java b/src/main/java/de/hhu/bsinfo/dxmem/data/ChunkState.java index 8c166ae..b570390 100755 --- a/src/main/java/de/hhu/bsinfo/dxmem/data/ChunkState.java +++ b/src/main/java/de/hhu/bsinfo/dxmem/data/ChunkState.java @@ -65,4 +65,9 @@ public enum ChunkState { * Typically, one simply issues the timed out operation again (maybe add a short delay). */ REMOTE_REQUEST_TIMEOUT, -} + + /** + * Chunk could not resized. + */ + RESIZE_FAILED +} \ No newline at end of file diff --git a/src/main/java/de/hhu/bsinfo/dxmem/operations/NoParamCheck.java b/src/main/java/de/hhu/bsinfo/dxmem/operations/NoParamCheck.java new file mode 100644 index 0000000..eb51b98 --- /dev/null +++ b/src/main/java/de/hhu/bsinfo/dxmem/operations/NoParamCheck.java @@ -0,0 +1,22 @@ +package de.hhu.bsinfo.dxmem.operations; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +/** + * Indicates that the parameters of the targets are not checked for having a better performance. + * It means that u have to take look into javadoc for this target how u use should use it. Remember it while debugging. + *
+ * In context of DXMem especially the Raw operations you can damage the memory structure. So use the target carefully + * + * @author Lars Mehnert + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(value = {TYPE, METHOD, CONSTRUCTOR}) +public @interface NoParamCheck { +} diff --git a/src/main/java/de/hhu/bsinfo/dxmem/operations/PinnedMemory.java b/src/main/java/de/hhu/bsinfo/dxmem/operations/PinnedMemory.java new file mode 100644 index 0000000..4662edf --- /dev/null +++ b/src/main/java/de/hhu/bsinfo/dxmem/operations/PinnedMemory.java @@ -0,0 +1,21 @@ +package de.hhu.bsinfo.dxmem.operations; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +/** + * Indicates that the class or the package presuppose, that they have to use in an context, where the memory is pinned. + * So you can use the target while you have pinned the memory but for other uses it is not safe that it will work. + * + * @author Lars Mehnert + * @see de.hhu.bsinfo.dxmem.operations.Pinning.PinnedMemory + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +@Target(value = {TYPE}) +public @interface PinnedMemory { +} diff --git a/src/main/java/de/hhu/bsinfo/dxmem/operations/RawCompare.java b/src/main/java/de/hhu/bsinfo/dxmem/operations/RawCompare.java new file mode 100644 index 0000000..4f2f1b7 --- /dev/null +++ b/src/main/java/de/hhu/bsinfo/dxmem/operations/RawCompare.java @@ -0,0 +1,60 @@ +package de.hhu.bsinfo.dxmem.operations; + +import de.hhu.bsinfo.dxmem.core.Context; + +/** + * A class for compare Operations based on physical addresses. + * + * @author Lars Mehnert + */ +@PinnedMemory +public class RawCompare { + + private final Context m_context; + + /** + * Constructor + * + * @param p_context Context + */ + public RawCompare(final Context p_context) { + m_context = p_context; + } + + /** + * Compare a byte at a given address + offset with a given byte. + * + * @param p_address physical address + * @param p_offset offset that will be added on p_address + * @param p_suspect byte which will be compared + * @return true if the given byte are equal to the read byte + */ + public boolean compare(final long p_address, final int p_offset, final byte p_suspect) { + return m_context.getHeap().readByte(p_address, p_offset) == p_suspect; + } + + /** + * Compares a byte array at a given address + offset with a given byte array. + * It iterates over the byte array and will return if it found a unequal at current iteration. + *
+ * Special attention to the range it will compare. The length of the given byte array is equal to the + * number of iterations. + * For the byte comparison it uses the {@link #compare(long, int, byte)} method. + * + * @param p_address physical address + * @param p_offset offset that will be added on p_address + * @param p_suspect byte array which will be compared + * @return true if the byte array is completely equal. + */ + public boolean compare(final long p_address, final int p_offset, final byte[] p_suspect) { + int offset = p_offset; + + for (byte b : p_suspect) { + if (!compare(p_address, offset, b)) + return false; + offset += Byte.BYTES; + } + return true; + } + +} diff --git a/src/main/java/de/hhu/bsinfo/dxmem/operations/RawRead.java b/src/main/java/de/hhu/bsinfo/dxmem/operations/RawRead.java index 60ba8f8..f0b677b 100644 --- a/src/main/java/de/hhu/bsinfo/dxmem/operations/RawRead.java +++ b/src/main/java/de/hhu/bsinfo/dxmem/operations/RawRead.java @@ -31,8 +31,7 @@ public class RawRead { /** * Constructor * - * @param p_context - * Context + * @param p_context Context */ public RawRead(final Context p_context) { m_context = p_context; @@ -70,6 +69,12 @@ public float readFloat(final long p_address, final int p_addressOffset) { return m_context.getHeap().readFloat(p_address, p_addressOffset); } + public byte[] readByteArray(final long p_address, final int p_addressOffset, final int p_length) { + byte[] arr = new byte[p_length]; + read(p_address, p_addressOffset, arr, 0, p_length); + return arr; + } + public void read(final long p_address, final int p_addressOffset, final boolean[] p_array) { read(p_address, p_addressOffset, p_array, 0, p_array.length); } @@ -103,42 +108,43 @@ public void read(final long p_address, final int p_addressOffset, final float[] } public void read(final long p_address, final int p_addressOffset, final boolean[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readBooleans(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final byte[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readBytes(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final short[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readShorts(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final char[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readChars(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final int[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readInts(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final long[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readLongs(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final double[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readDoubles(p_address, p_addressOffset, p_array, p_offset, p_length); } public void read(final long p_address, final int p_addressOffset, final float[] p_array, final int p_offset, - final int p_length) { + final int p_length) { m_context.getHeap().readFloats(p_address, p_addressOffset, p_array, p_offset, p_length); } + } diff --git a/src/main/java/de/hhu/bsinfo/dxmem/operations/Resize.java b/src/main/java/de/hhu/bsinfo/dxmem/operations/Resize.java index e15da03..f199772 100644 --- a/src/main/java/de/hhu/bsinfo/dxmem/operations/Resize.java +++ b/src/main/java/de/hhu/bsinfo/dxmem/operations/Resize.java @@ -44,8 +44,7 @@ public class Resize { /** * Constructor * - * @param p_context - * Context + * @param p_context Context */ public Resize(final Context p_context) { m_context = p_context; @@ -54,10 +53,8 @@ public Resize(final Context p_context) { /** * Resize an existing chunk * - * @param p_cid - * CID of chunk to resize - * @param p_newSize - * New size for chunk + * @param p_cid CID of chunk to resize + * @param p_newSize New size for chunk * @return True if succcessful, false on failure */ public ChunkState resize(final long p_cid, final int p_newSize) { @@ -67,19 +64,15 @@ public ChunkState resize(final long p_cid, final int p_newSize) { /** * Resize an existing chunk * - * @param p_cid - * CID of chunk to resize - * @param p_newSize - * New size for chunk - * @param p_lockOperation - * Lock operation to execute for chunk to resize - * @param p_lockTimeoutMs - * If a lock operation is set, set to -1 for infinite retries (busy polling) until the lock operation - * succeeds. 0 for a one shot try and > 0 for a timeout value in ms + * @param p_cid CID of chunk to resize + * @param p_newSize New size for chunk + * @param p_lockOperation Lock operation to execute for chunk to resize + * @param p_lockTimeoutMs If a lock operation is set, set to -1 for infinite retries (busy polling) until the lock operation + * succeeds. 0 for a one shot try and > 0 for a timeout value in ms * @return True if succcessful, false on failure */ public ChunkState resize(final long p_cid, final int p_newSize, final ChunkLockOperation p_lockOperation, - final int p_lockTimeoutMs) { + final int p_lockTimeoutMs) { assert assertLockOperationSupport(p_lockOperation); assert p_newSize > 0; @@ -114,7 +107,9 @@ public ChunkState resize(final long p_cid, final int p_newSize, final ChunkLockO return ChunkState.DOES_NOT_EXIST; } - m_context.getHeap().resize(tableEntry, p_newSize); + if (!m_context.getHeap().resize(tableEntry, p_newSize)) { + return ChunkState.RESIZE_FAILED; + } // update cid table entry m_context.getCIDTable().entryUpdate(tableEntry);