pax_global_header00006660000000000000000000000064122675237510014524gustar00rootroot0000000000000052 comment=22a7677f7ed248fb29568839c3c5e03df25e8eb1 Java-Lang-6.1.4/000077500000000000000000000000001226752375100132745ustar00rootroot00000000000000Java-Lang-6.1.4/.gitignore000066400000000000000000000001251226752375100152620ustar00rootroot00000000000000*.class # Package Files # *.jar *.war *.ear # IntelliJ *.iml .idea # maven target Java-Lang-6.1.4/.idea/000077500000000000000000000000001226752375100142545ustar00rootroot00000000000000Java-Lang-6.1.4/.idea/copyright/000077500000000000000000000000001226752375100162645ustar00rootroot00000000000000Java-Lang-6.1.4/.idea/copyright/Apache_2_0.xml000066400000000000000000000016551226752375100206360ustar00rootroot00000000000000 Java-Lang-6.1.4/README.md000066400000000000000000000061541226752375100145610ustar00rootroot00000000000000#JavaLang This module provides marshalling, de-marshalling and handling of thread safe off heap memory through ByteBuffers. This module is available on maven central as net.openhft lang 6.1.1 The version 6.x signifies that it is build for Java 6+. (It requires Java 6 update 18 or later to build) ## Working with off heap objects. Java-Lang 6.1 adds support for basic off heap data structures. More collections types and more complex data types will be added in future versions. public interface DataType { // add getters and setters here } // can create an array of any size (provided you have the memory) off heap. HugeArray array = HugeCollections.newArray(DataType.class, 10*1000*1000*1000L); DataType dt = array.get(1111111111); // set data on dt array.recycle(dt); // recycle the reference (or discard it) // create a ring buffer HugeQueue queue = HugeCollections.newQueue(DataType.class, 10*1000*1000L); // give me a reference to an object to populate DataType dt2 = queue.offer(); // set the values od dt2 queue.recycle(dt2); DataType dt3 = queue.take(); // get values queue.recycle(dt3); This is designed to be largely GC-less and you can queue millions of entries with 32 MB heap and not trigger GCs. ## Working with buffers To work with buffers there is a several options: * _ByteBufferBytes_ which wraps [java.nio.ByteBuffer](http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html) * _DirectBytes_ which is slices/records of [DirectStore](https://github.com/OpenHFT/Java-Lang/blob/master/lang/src/main/java/net/openhft/lang/io/DirectStore.java) - own implementation for offheap storage Both classes provide functionality: * write\read operations for primitives (writeLong(long n), readLong() etc.) * locking in native memory, so you can add thread safe constructs to your native record. * CAS operations for int and long _boolean compareAndSwapInt(long offset, int expected, int x)_, _boolean compareAndSwapLong(long offset, long expected, long x)_ * addAndGetInt and getAndAddInt operations ####Example ByteBuffer byteBuffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder()); ByteBufferBytes bytes = new ByteBufferBytes(byteBuffer); for (long i = 0; i < bytes.capacity(); i++) bytes.writeLong(i); for (long i = bytes.capacity()-8; i >= 0; i -= 8) { int j = bytes.readLong(i); assert i == j; } #Building for eclipse Download Java-Lang zip from git https://github.com/OpenHFT/Java-Lang/archive/master.zip Unzip master.zip, Java-Lang-master folder will be extracted from zip. cd Java-Lang-master mvn eclipse:eclipse Now you have an eclipse project, import project into Eclipse If your Eclipse configuration is not UTF-8, after importing the project you may see some errors and strange characters in some .java files. To get rid of this problem change character enconding to UTF-8: project->properties->resource->text file encoding->utf8 Java-Lang-6.1.4/lang-integration/000077500000000000000000000000001226752375100165365ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/pom.xml000077500000000000000000000103021226752375100200520ustar00rootroot00000000000000 4.0.0 net.openhft lang-integration 6.1.3 pom OpenHFT/Java-Lang/lang-osgi Java Lang library for High Frequency Trading (Java 6+) UTF-8 net.openhft lang ${project.version} net.openhft affinity 2.0.1 test junit junit 4.11 test src/test/java org.apache.maven.plugins maven-compiler-plugin 3.1 1.6 1.6 UTF-8 org.apache.maven.plugins maven-source-plugin 2.2 attach-sources verify jar org.apache.maven.plugins maven-javadoc-plugin 2.9 attach-javadocs verify jar public true http://www.openhft.net The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo A business-friendly OSS license Peter Lawrey peter.lawrey@higherfrequencytrading.com scm:git:https://github.com/OpenHFT/Java-Lang.git Java-Lang-6.1.4/lang-integration/src/000077500000000000000000000000001226752375100173255ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/000077500000000000000000000000001226752375100203045ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/java/000077500000000000000000000000001226752375100212255ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/java/net/000077500000000000000000000000001226752375100220135ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/java/net/openhft/000077500000000000000000000000001226752375100234565ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/java/net/openhft/lang/000077500000000000000000000000001226752375100243775ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/java/net/openhft/lang/io/000077500000000000000000000000001226752375100250065ustar00rootroot00000000000000LockingViaMMapWithThreadIdMain.java000066400000000000000000000102031226752375100334350ustar00rootroot00000000000000Java-Lang-6.1.4/lang-integration/src/test/java/net/openhft/lang/io/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.affinity.AffinitySupport; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; /** * User: peter * Date: 22/12/13 * Time: 11:05 *

* Toggled 10,000,128 times with an average delay of 20 ns on i7-4700 * Toggled 10,000,128 times with an average delay of 14 ns on i7-3970X */ public class LockingViaMMapWithThreadIdMain { static int RECORDS = Integer.getInteger("records", 256); static int RECORD_SIZE = Integer.getInteger("record_size", 64); // double cache line size static int WARMUP = Integer.getInteger("warmup", RECORDS * 50); static int RUNS = Integer.getInteger("runs", 50 * 1000 * 1000); // offsets static int LOCK = 0; static int FLAG = 8; static int LENGTH = 16; public static void main(String... args) throws IOException, InterruptedException { boolean toggleTo = Boolean.parseBoolean(args[0]); File tmpFile = new File(System.getProperty("java.io.tmpdir"), "lock-test-tid.dat"); FileChannel fc = new RandomAccessFile(tmpFile, "rw").getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, RECORDS * RECORD_SIZE); // set the the Thread.getId() to match the process thread id // this way the getId() can be used across processes.. AffinitySupport.setThreadId(); AffinitySupport.setAffinity(toggleTo ? 1 << 3 : 1 << 2); ByteBufferBytes bytes = new ByteBufferBytes(mbb.order(ByteOrder.nativeOrder())); bytes.setCurrentThread(); long start = 0; for (int i = -WARMUP / RECORDS; i < (RUNS + RECORDS - 1) / RECORDS; i++) { if (i == 0) { start = System.nanoTime(); System.out.println("Started"); } for (int j = 0; j < RECORDS; j++) { int recordOffset = j * RECORD_SIZE; for (int t = 1; t < 10000; t++) { if (t == 0) if (i >= 0) { throw new AssertionError("Didn't toggle in time !??"); } else { Thread.sleep(200); } bytes.busyLockInt(recordOffset + LOCK); try { boolean flag = bytes.readBoolean(recordOffset + FLAG); if (flag != toggleTo) { bytes.writeBoolean(recordOffset + FLAG, toggleTo); break; } } finally { bytes.unlockInt(recordOffset + LOCK); } if (t % 100 == 0) System.out.println("waiting for " + j + " pid " + (bytes.readInt(recordOffset + LOCK) & (-1 >>> 8)) + " is " + bytes.readBoolean(recordOffset + FLAG)); if (t > 100) if (t > 200) Thread.sleep(1); else Thread.yield(); } } } long time = System.nanoTime() - start; final int toggles = (RUNS + RECORDS - 1) / RECORDS * RECORDS * 2; // one for each of two processes. System.out.printf("Toggled %,d times with an average delay of %,d ns%n", toggles, time / toggles); fc.close(); tmpFile.deleteOnExit(); } } Java-Lang-6.1.4/lang-osgi/000077500000000000000000000000001226752375100151545ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/pom.xml000077500000000000000000000170321226752375100164770ustar00rootroot00000000000000 4.0.0 net.openhft lang-osgi 6.1.3 bundle OpenHFT/Java-Lang/lang-osgi Java Lang library for High Frequency Trading (Java 6+) UTF-8 3.2.2 3.3.0 1.6.0 org.kohsuke.jetbrains annotations 9.0 compile net.openhft lang ${project.version} junit junit 4.11 test org.ops4j.pax.exam pax-exam-container-native ${pax.exam.version} test org.ops4j.pax.exam pax-exam-junit4 ${pax.exam.version} test org.ops4j.pax.exam pax-exam-link-mvn ${pax.exam.version} test org.ops4j.pax.url pax-url-aether ${pax.url.version} test org.apache.felix org.apache.felix.framework ${felix.version} test ch.qos.logback logback-core 0.9.6 test ch.qos.logback logback-classic 0.9.6 test src/test/java org.apache.maven.plugins maven-compiler-plugin 3.1 1.6 1.6 UTF-8 org.apache.maven.plugins maven-source-plugin 2.2 attach-sources verify jar org.apache.maven.plugins maven-javadoc-plugin 2.9 attach-javadocs verify jar public true org.apache.felix maven-bundle-plugin 2.3.7 true ${project.groupId}.${project.artifactId} ${project.artifactId} manifest http://www.openhft.net The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo A business-friendly OSS license Peter Lawrey peter.lawrey@higherfrequencytrading.com scm:git:https://github.com/OpenHFT/Java-Lang.git Java-Lang-6.1.4/lang-osgi/src/000077500000000000000000000000001226752375100157435ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/000077500000000000000000000000001226752375100166675ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/java/000077500000000000000000000000001226752375100176105ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/java/net/000077500000000000000000000000001226752375100203765ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/java/net/openhft/000077500000000000000000000000001226752375100220415ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/java/net/openhft/langosgi/000077500000000000000000000000001226752375100236445ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/java/net/openhft/langosgi/model/000077500000000000000000000000001226752375100247445ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/main/java/net/openhft/langosgi/model/JavaBeanInterface.java000066400000000000000000000025641226752375100311060ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.langosgi.model; import net.openhft.lang.model.constraints.MaxSize; /** * User: peter.lawrey Date: 06/10/13 Time: 16:59 */ public interface JavaBeanInterface { int getRecord(); void setRecord(int record); void busyLockRecord() throws InterruptedException; void unlockRecord(); void setFlag(boolean flag); boolean getFlag(); void setByte(byte b); byte getByte(); void setShort(short s); short getShort(); void setChar(char ch); char getChar(); void setInt(int i); int getInt(); void setFloat(float f); float getFloat(); void setLong(long l); long getLong(); void setDouble(double d); double getDouble(); void setString(@MaxSize(8) String s); String getString(); } Java-Lang-6.1.4/lang-osgi/src/test/000077500000000000000000000000001226752375100167225ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/test/java/000077500000000000000000000000001226752375100176435ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/test/java/net/000077500000000000000000000000001226752375100204315ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/test/java/net/openhft/000077500000000000000000000000001226752375100220745ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/test/java/net/openhft/lang/000077500000000000000000000000001226752375100230155ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/test/java/net/openhft/lang/osgi/000077500000000000000000000000001226752375100237565ustar00rootroot00000000000000Java-Lang-6.1.4/lang-osgi/src/test/java/net/openhft/lang/osgi/OSGiBundleTest.java000066400000000000000000000056671226752375100274320ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.osgi; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.slf4j.LoggerFactory; import javax.inject.Inject; import java.io.File; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.ops4j.pax.exam.CoreOptions.*; /** * @author lburgazzoli */ @RunWith(PaxExam.class) public class OSGiBundleTest { @Inject BundleContext context; @Configuration public Option[] config() { Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); root.setLevel(Level.INFO); return options( systemProperty("org.osgi.framework.storage.clean").value("true"), systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("WARN"), mavenBundle("net.openhft", "compiler", "2.1"), new File("Java-Lang/lang/target/classes").exists() ? bundle("reference:file:Java-Lang/lang/target/classes") : bundle("reference:file:../lang/target/classes"), new File("Java-Lang/lang-osgi/target/classes").exists() ? bundle("reference:file:Java-Lang/lang-osgi/target/classes") : bundle("reference:file:target/classes"), junitBundles(), systemPackage("sun.misc"), systemPackage("sun.nio.ch"), systemPackage("com.sun.tools.javac.api"), cleanCaches() ); } @Test public void checkInject() { assertNotNull(context); } @Test public void checkHelloBundle() { Boolean bundleFound = false; Boolean bundleActive = false; Bundle[] bundles = context.getBundles(); for (Bundle bundle : bundles) { if (bundle != null) { if (bundle.getSymbolicName().equals("net.openhft.lang")) { bundleFound = true; if (bundle.getState() == Bundle.ACTIVE) { bundleActive = true; } } } } assertTrue(bundleFound); assertTrue(bundleActive); } } Java-Lang-6.1.4/lang-osgi/src/test/java/net/openhft/lang/osgi/OSGiCollectionTest.java000066400000000000000000000051301226752375100302750ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.osgi; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import net.openhft.lang.collection.HugeArray; import net.openhft.lang.collection.HugeCollections; import net.openhft.langosgi.model.JavaBeanInterface; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.osgi.framework.BundleContext; import org.slf4j.LoggerFactory; import javax.inject.Inject; import java.io.File; import static org.junit.Assert.assertNotNull; import static org.ops4j.pax.exam.CoreOptions.*; /** * @author lburgazzoli */ @Ignore @RunWith(PaxExam.class) public class OSGiCollectionTest { @Inject BundleContext context; @Configuration public Option[] config() { Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); root.setLevel(Level.INFO); return options( systemProperty("org.osgi.framework.storage.clean").value("true"), systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("WARN"), mavenBundle("net.openhft", "compiler", "2.1"), new File("Java-Lang/lang/target/classes").exists() ? bundle("reference:file:Java-Lang/lang/target/classes") : bundle("reference:file:../lang/target/classes"), new File("Java-Lang/lang-osgi/target/classes").exists() ? bundle("reference:file:Java-Lang/lang-osgi/target/classes") : bundle("reference:file:target/classes"), junitBundles(), systemPackage("sun.misc"), systemPackage("sun.nio.ch"), systemPackage("com.sun.tools.javac.api"), cleanCaches() ); } @Test public void checkHugeArray() { int length = 10 * 1000 * 1000; HugeArray array = HugeCollections.newArray(JavaBeanInterface.class, length); assertNotNull(array); } } Java-Lang-6.1.4/lang/000077500000000000000000000000001226752375100142155ustar00rootroot00000000000000Java-Lang-6.1.4/lang/.gitignore000066400000000000000000000000231226752375100162000ustar00rootroot00000000000000*.ipr *.iws target/Java-Lang-6.1.4/lang/pom.xml000077500000000000000000000141471226752375100155440ustar00rootroot00000000000000 4.0.0 net.openhft lang 6.1.4-SNAPSHOT bundle OpenHFT/Java-Lang/lang Java Lang library for High Frequency Trading (Java 6+) UTF-8 3.2.2 3.3.0 1.6.0 org.kohsuke.jetbrains annotations 9.0 compile net.openhft compiler 2.1 true org.easymock easymock 3.1 test junit junit 4.11 test org.apache.maven.plugins maven-compiler-plugin 3.1 1.6 1.6 UTF-8 org.apache.maven.plugins maven-source-plugin 2.2 attach-sources verify jar org.apache.maven.plugins maven-javadoc-plugin 2.9 attach-javadocs verify jar public true org.apache.felix maven-bundle-plugin 2.3.7 true ${project.groupId}.${project.artifactId} ${project.artifactId} manifest http://www.openhft.net The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo A business-friendly OSS license Peter Lawrey peter.lawrey@higherfrequencytrading.com scm:git:https://github.com/OpenHFT/Java-Lang.git Java-Lang-6.1.4/lang/src/000077500000000000000000000000001226752375100150045ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/000077500000000000000000000000001226752375100157305ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/000077500000000000000000000000001226752375100166515ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/000077500000000000000000000000001226752375100174375ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/000077500000000000000000000000001226752375100211025ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/000077500000000000000000000000001226752375100220235ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/Compare.java000066400000000000000000000123211226752375100242530ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang; /** * A generic Compare class for many types. It can be sub-classed so you can give types a different behaviour. */ public abstract class Compare { private static final long NULL_HASHCODE = Long.MIN_VALUE; public static boolean isEqual(boolean a, boolean b) { return a == b; } public static long calcLongHashCode(boolean a) { return a ? 1 : 0; } public static boolean isEqual(Boolean a, Boolean b) { return a == null ? b == null : b != null && a.booleanValue() == b.booleanValue(); } public static long calcLongHashCode(Boolean a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.booleanValue()); } public static boolean isEqual(byte a, byte b) { return a == b; } public static long calcLongHashCode(byte a) { return a; } public static boolean isEqual(Byte a, Byte b) { return a == null ? b == null : b != null && a.byteValue() == b.byteValue(); } public static long calcLongHashCode(Byte a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.byteValue()); } public static boolean isEqual(char a, char b) { return a == b; } public static long calcLongHashCode(char a) { return a; } public static boolean isEqual(Character a, Character b) { return a == null ? b == null : b != null && a.charValue() == b.charValue(); } public static long calcLongHashCode(Character a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.charValue()); } public static boolean isEqual(short a, short b) { return a == b; } public static long calcLongHashCode(short a) { return a; } public static boolean isEqual(Short a, Short b) { return a == null ? b == null : b != null && a.shortValue() == b.shortValue(); } public static long calcLongHashCode(Short a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.shortValue()); } public static boolean isEqual(int a, int b) { return a == b; } public static long calcLongHashCode(int a) { return a; } public static long calcLongHashCode(Integer a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.intValue()); } public static boolean isEqual(Integer a, Integer b) { return a == null ? b == null : b != null && a.intValue() == b.intValue(); } public static boolean isEqual(long a, long b) { return a == b; } public static long calcLongHashCode(long a) { return a; } public static boolean isEqual(Long a, Long b) { return a == null ? b == null : b != null && a.longValue() == b.longValue(); } public static long calcLongHashCode(Long a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.longValue()); } public static boolean isEqual(float a, float b) { return Float.floatToRawIntBits(a) == Float.floatToRawIntBits(b); } public static long calcLongHashCode(float a) { return Float.floatToRawIntBits(a); } public static boolean isEqual(Float a, Float b) { return a == null ? b == null : b != null && isEqual(a.floatValue(), b.floatValue()); } public static long calcLongHashCode(Float a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.floatValue()); } public static boolean isEqual(double a, double b) { return Double.doubleToRawLongBits(a) == Double.doubleToRawLongBits(b); } public static long calcLongHashCode(double a) { return Double.doubleToRawLongBits(a); } public static boolean isEqual(Double a, Double b) { return a == null ? b == null : b != null && isEqual(a.doubleValue(), b.doubleValue()); } public static long calcLongHashCode(Double a) { return a == null ? NULL_HASHCODE : calcLongHashCode(a.doubleValue()); } public static boolean isEqual(T a, T b) { return a == null ? b == null : b != null && a.equals(b); } public static long calcLongHashCode(LongHashable t) { return t.longHashCode(); } public static long calcLongHashCode(Object t) { return t == null ? NULL_HASHCODE : t instanceof LongHashable ? calcLongHashCode((LongHashable) t) : t instanceof CharSequence ? calcLongHashCode((CharSequence) t) : t.hashCode(); } public static long calcLongHashCode(CharSequence s) { long hash = 0; for (int i = 0, len = s.length(); i < len; i++) { hash = 57 * hash + s.charAt(i); } return hash; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/Jvm.java000077500000000000000000000053161226752375100234320ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang; import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.util.Random; import java.util.logging.Logger; /** * @author peter.lawrey */ public enum Jvm { ; public static final String TMP = System.getProperty("java.io.tmpdir"); private static final boolean IS64BIT = is64Bit0(); public static boolean is64Bit() { return IS64BIT; } private static boolean is64Bit0() { String systemProp; systemProp = System.getProperty("com.ibm.vm.bitmode"); if (systemProp != null) { return "64".equals(systemProp); } systemProp = System.getProperty("sun.arch.data.model"); if (systemProp != null) { return "64".equals(systemProp); } systemProp = System.getProperty("java.vm.version"); return systemProp != null && systemProp.contains("_64"); } private static final int PROCESS_ID = getProcessId0(); public static int getProcessId() { return PROCESS_ID; } private static int getProcessId0() { String pid = null; final File self = new File("/proc/self"); try { if (self.exists()) pid = self.getCanonicalFile().getName(); } catch (IOException ignored) { // ignored } if (pid == null) pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; if (pid == null) { int rpid = new Random().nextInt(1 << 16); Logger.getLogger(Jvm.class.getName()).warning("Unable to determine PID, picked a random number=" + rpid); return rpid; } else { return Integer.parseInt(pid); } } /** * This may or may not be the OS thread id, but should be unique across processes * * @return a unique tid of up to 48 bits. */ public static long getUniqueTid() { return getUniqueTid(Thread.currentThread()); } public static long getUniqueTid(Thread thread) { return (long) getProcessId() << 32 | (thread.getId() & 0xFFFFFFFFL); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/LongHashable.java000066400000000000000000000013561226752375100252220ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang; /** * User: peter.lawrey * Date: 08/10/13 * Time: 12:44 */ public interface LongHashable { long longHashCode(); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/Maths.java000077500000000000000000000117671226752375100237610ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang; /** * @author peter.lawrey */ public class Maths { /** * Numbers larger than this are whole numbers due to representation error. */ public static final double WHOLE_NUMBER = 1L << 53; private static final long[] TENS = new long[19]; static { TENS[0] = 1; for (int i = 1; i < TENS.length; i++) TENS[i] = TENS[i - 1] * 10; } /** * Performs a round which is accurate to within 1 ulp. i.e. for values very close to 0.5 it might be rounded up or * down. This is a pragmatic choice for performance reasons as it is assumed you are not working on the edge of the * precision of double. * * @param d value to round */ public static double round2(double d) { final double factor = 1e2; return d > WHOLE_NUMBER || d < -WHOLE_NUMBER ? d : (long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor; } /** * Performs a round which is accurate to within 1 ulp. i.e. for values very close to 0.5 it might be rounded up or * down. This is a pragmatic choice for performance reasons as it is assumed you are not working on the edge of the * precision of double. * * @param d value to round */ public static double round4(double d) { final double factor = 1e4; return d > Long.MAX_VALUE / factor || d < -Long.MAX_VALUE / factor ? d : (long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor; } /** * Performs a round which is accurate to within 1 ulp. i.e. for values very close to 0.5 it might be rounded up or * down. This is a pragmatic choice for performance reasons as it is assumed you are not working on the edge of the * precision of double. * * @param d value to round */ public static double round6(double d) { final double factor = 1e6; return d > Long.MAX_VALUE / factor || d < -Long.MAX_VALUE / factor ? d : (long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor; } /** * Performs a round which is accurate to within 1 ulp. i.e. for values very close to 0.5 it might be rounded up or * down. This is a pragmatic choice for performance reasons as it is assumed you are not working on the edge of the * precision of double. * * @param d value to round */ public static double round8(double d) { final double factor = 1e8; return d > Long.MAX_VALUE / factor || d < -Long.MAX_VALUE / factor ? d : (long) (d < 0 ? d * factor - 0.5 : d * factor + 0.5) / factor; } public static long power10(int n) { if (n < 0 || n >= TENS.length) return -1; return TENS[n]; } public static int nextPower2(int n, int min) { if (n < min) return min; if ((n & (n - 1)) == 0) return n; int i = min; while (i < n) { i *= 2; if (i <= 0) return 1 << 30; } return i; } public static long nextPower2(long n, long min) { if (n < min) return min; if ((n & (n - 1)) == 0) return n; long i = min; while (i < n) { i *= 2; if (i <= 0) return 1L << 62; } return i; } public static int hash(int n) { n ^= (n >> 21) ^ (n >> 11); n ^= (n >> 7) ^ (n >> 4); return n; } public static int hash(long n) { n ^= (n >> 43) ^ (n >> 21); n ^= (n >> 15) ^ (n >> 7); return (int) n; } public static long hash(CharSequence cs) { long hash = 0; for (int i = 0; i < cs.length(); i++) hash = hash * 131 + cs.charAt(i); return hash; } /** * Compares two {@code long} values numerically. The value returned is identical to what would be returned by: *

     *    Long.valueOf(x).compareTo(Long.valueOf(y))
     * 
* * @param x the first {@code long} to compare * @param y the second {@code long} to compare * @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if {@code x < y}; and a value greater * than {@code 0} if {@code x > y} */ public static int compare(long x, long y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); } public static int intLog2(long num) { long l = Double.doubleToRawLongBits(num); return (int) ((l >> 52) - 1023); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/000077500000000000000000000000001226752375100241565ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/HugeArray.java000066400000000000000000000031761226752375100267170ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection; /** * User: peter.lawrey * Date: 08/10/13 * Time: 07:40 */ public interface HugeArray { /** * @return the capacity of the Array. */ long length(); /** * Get a recycled object which is a reference to this element. * * @param index to look up. * @return object reference to the element. */ T get(long index); /** * Get a copy of the object in the array * * @param index of element to copy * @param element Copyable element to copy to. */ void get(long index, T element); /** * Copy the contents of an index to another object * * @param index to copy * @param to object */ void copyTo(long index, T to); /** * Set the data in the array to a copy of this element * * @param index to copy to * @param t to copy */ void set(long index, T t); /** * recycle the reference, * * @param t reference to recycle. */ void recycle(T t); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/HugeCollections.java000066400000000000000000000027331226752375100301150ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection; import net.openhft.lang.collection.impl.HugeArrayImpl; import net.openhft.lang.collection.impl.HugeQueueImpl; import net.openhft.lang.model.DataValueGenerator; /** * User: peter.lawrey * Date: 08/10/13 * Time: 08:09 */ public enum HugeCollections { ; private static final DataValueGenerator VALUE_GENERATOR = new DataValueGenerator(); static { VALUE_GENERATOR.setDumpCode(true); } public static DataValueGenerator getDataValueGenerator() { return VALUE_GENERATOR; } public static HugeArray newArray(Class tClass, long length) { return new HugeArrayImpl(VALUE_GENERATOR, tClass, length); } public static HugeQueue newQueue(Class tClass, long length) { return new HugeQueueImpl(new HugeArrayImpl(VALUE_GENERATOR, tClass, length + 1), length + 1); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/HugeQueue.java000066400000000000000000000030771226752375100267250ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection; /** * User: peter.lawrey * Date: 08/10/13 * Time: 13:26 */ public interface HugeQueue { /** * @return is full */ boolean isFull(); /** * @return is empty */ boolean isEmpty(); /** * Add to the end of a queue or return false if full. * * @return an element to populate or null if full */ T offer(); /** * Add to the end of a queue or return false if full. * * @param element to add * @return true if added or false if full. */ boolean offer(T element); /** * @return the element or null is non is available */ T take(); /** * Copy data to an element * * @param element to copy to * @return true if one was available or false if not. */ boolean takeCopy(T element); /** * Recycle an element reference. * * @param element reference to recycle. */ void recycle(T element); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/impl/000077500000000000000000000000001226752375100251175ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/impl/HugeArrayImpl.java000066400000000000000000000063161226752375100305010ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection.impl; import net.openhft.lang.collection.HugeArray; import net.openhft.lang.io.DirectBytes; import net.openhft.lang.io.DirectStore; import net.openhft.lang.model.Byteable; import net.openhft.lang.model.Copyable; import net.openhft.lang.model.DataValueGenerator; import java.util.ArrayList; import java.util.List; /** * User: peter.lawrey Date: 08/10/13 Time: 08:11 */ public class HugeArrayImpl implements HugeArray { private static final int MAX_SIZE = 10; private final DataValueGenerator valueGenerator; private final Class tClass; private final long length; private final int size; private final DirectStore store; private final List freeList = new ArrayList(MAX_SIZE); public HugeArrayImpl(DataValueGenerator valueGenerator, Class tClass, long length) { this.valueGenerator = valueGenerator; this.tClass = tClass; this.length = length; T ref = valueGenerator.nativeInstance(tClass); size = ((Byteable) ref).maxSize(); store = new DirectStore(null, length * size); ((Byteable) ref).bytes(store.createSlice()); recycle(ref); } private T createRef() { T ref = valueGenerator.nativeInstance(tClass); ((Byteable) ref).bytes(store.createSlice()); return ref; } @Override public long length() { return length; } @Override public T get(long index) { T t = acquire(); DirectBytes bytes = (DirectBytes) ((Byteable) t).bytes(); bytes.positionAndSize(index * size, size); return t; } @Override public void get(long index, T element) { T t = acquire(); DirectBytes bytes = (DirectBytes) ((Byteable) t).bytes(); bytes.positionAndSize(index * size, size); ((Copyable) element).copyFrom(t); recycle(t); } private T acquire() { int size = freeList.size(); if (size > 0) return freeList.remove(size - 1); return createRef(); } @Override public void copyTo(long index, T to) { T from = get(index); ((Copyable) to).copyFrom(from); recycle(from); } @Override public void set(long index, T from) { T to = get(index); ((Copyable) to).copyFrom(from); recycle(to); } @Override public void recycle(T t) { if (freeList.size() < MAX_SIZE) { assert ((DirectBytes) ((Byteable) t).bytes()).store() == store; assert !freeList.contains(t) : "recycling object already recycled"; freeList.add(t); } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/collection/impl/HugeQueueImpl.java000066400000000000000000000041241226752375100305020ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection.impl; import net.openhft.lang.collection.HugeArray; import net.openhft.lang.collection.HugeQueue; /** * User: peter.lawrey * Date: 08/10/13 * Time: 13:31 */ public class HugeQueueImpl implements HugeQueue { private final HugeArray array; private final long size; private long start, end; public HugeQueueImpl(HugeArray tHugeArray, long size) { array = tHugeArray; this.size = size; } public boolean isFull() { return next(end) == start; } private long next(long end) { return (end + 1) % size; } public boolean isEmpty() { return end == start; } @Override public boolean offer(T element) { if (isFull()) return false; array.set(end % size, element); end = next(end); return true; } @Override public T take() { if (isEmpty()) return null; long pos = start % size; start = next(start); return array.get(pos); } @Override public boolean takeCopy(T element) { if (isEmpty()) return false; array.get(start % size, element); start = next(start); return true; } @Override public T offer() { if (isFull()) return null; T t = array.get(end % size); end = next(end); return t; } @Override public void recycle(T element) { array.recycle(element); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/000077500000000000000000000000001226752375100224325ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/AbstractBytes.java000077500000000000000000002140221226752375100260530ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.Jvm; import net.openhft.lang.Maths; import net.openhft.lang.io.serialization.BytesMarshallable; import net.openhft.lang.io.serialization.BytesMarshaller; import net.openhft.lang.io.serialization.BytesMarshallerFactory; import net.openhft.lang.io.serialization.CompactBytesMarshaller; import net.openhft.lang.io.serialization.impl.NoMarshaller; import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory; import net.openhft.lang.pool.StringInterner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; /** * @author peter.lawrey */ @SuppressWarnings("MagicNumber") public abstract class AbstractBytes implements Bytes { public static final long BUSY_LOCK_LIMIT = 10L * 1000 * 1000 * 1000; public static final int INT_LOCK_MASK = 0xFFFFFF; public static final int UNSIGNED_BYTE_MASK = 0xFF; public static final int UNSIGNED_SHORT_MASK = 0xFFFF; public static final long UNSIGNED_INT_MASK = 0xFFFFFFFFL; // extra 1 for decimal place. static final int MAX_NUMBER_LENGTH = 1 + (int) Math.ceil(Math.log10(Long.MAX_VALUE)); static final byte[] RADIX_PARSE = new byte[256]; static { Arrays.fill(RADIX_PARSE, (byte) -1); for (int i = 0; i < 10; i++) RADIX_PARSE['0' + i] = (byte) i; for (int i = 0; i < 26; i++) RADIX_PARSE['A' + i] = RADIX_PARSE['a' + i] = (byte) (i + 10); } private static final Logger LOGGER = Logger.getLogger(AbstractBytes.class.getName()); private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); private static final byte[] MIN_VALUE_TEXT = ("" + Long.MIN_VALUE).getBytes(); private static final byte[] Infinity = "Infinity".getBytes(); private static final byte[] NaN = "NaN".getBytes(); private static final long MAX_VALUE_DIVIDE_5 = Long.MAX_VALUE / 5; private static final byte BYTE_MIN_VALUE = Byte.MIN_VALUE; private static final byte BYTE_EXTENDED = Byte.MIN_VALUE + 1; private static final byte BYTE_MAX_VALUE = Byte.MIN_VALUE + 2; private static final short UBYTE_EXTENDED = 0xff; private static final short SHORT_MIN_VALUE = Short.MIN_VALUE; private static final short SHORT_EXTENDED = Short.MIN_VALUE + 1; private static final short SHORT_MAX_VALUE = Short.MIN_VALUE + 2; private static final int USHORT_EXTENDED = UNSIGNED_SHORT_MASK; // RandomDataInput private static final int INT_MIN_VALUE = Integer.MIN_VALUE; private static final int INT_EXTENDED = Integer.MIN_VALUE + 1; private static final int INT_MAX_VALUE = Integer.MIN_VALUE + 2; private static final long MAX_VALUE_DIVIDE_10 = Long.MAX_VALUE / 10; private static final byte NULL = 'N'; private static final byte ENUMED = 'E'; private static final byte SERIALIZED = 'S'; private static final byte[] RADIX = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes(); static boolean ID_LIMIT_WARNED = false; private final byte[] numberBuffer = new byte[MAX_NUMBER_LENGTH]; protected boolean finished; protected BytesMarshallerFactory bytesMarshallerFactory; private StringInterner stringInterner = null; private BytesInputStream inputStream = null; private BytesOutputStream outputStream = null; private StringBuilder utfReader = null; private SimpleDateFormat dateFormat = null; private long lastDay = Long.MIN_VALUE; @Nullable private byte[] lastDateStr = null; protected AbstractBytes() { this(new VanillaBytesMarshallerFactory()); } protected AbstractBytes(BytesMarshallerFactory bytesMarshallerFactory) { this.finished = false; this.bytesMarshallerFactory = bytesMarshallerFactory; } static boolean equalsCaseIgnore(StringBuilder sb, String s) { if (sb.length() != s.length()) return false; for (int i = 0; i < s.length(); i++) if (Character.toLowerCase(sb.charAt(i)) != s.charAt(i)) return false; return true; } private static double asDouble(long value, int exp, boolean negative, int decimalPlaces) { if (decimalPlaces > 0 && value < Long.MAX_VALUE / 2) { if (value < Long.MAX_VALUE / (1L << 32)) { exp -= 32; value <<= 32; } if (value < Long.MAX_VALUE / (1L << 16)) { exp -= 16; value <<= 16; } if (value < Long.MAX_VALUE / (1L << 8)) { exp -= 8; value <<= 8; } if (value < Long.MAX_VALUE / (1L << 4)) { exp -= 4; value <<= 4; } if (value < Long.MAX_VALUE / (1L << 2)) { exp -= 2; value <<= 2; } if (value < Long.MAX_VALUE / (1L << 1)) { exp -= 1; value <<= 1; } } for (; decimalPlaces > 0; decimalPlaces--) { exp--; long mod = value % 5; value /= 5; int modDiv = 1; if (value < Long.MAX_VALUE / (1L << 4)) { exp -= 4; value <<= 4; modDiv <<= 4; } if (value < Long.MAX_VALUE / (1L << 2)) { exp -= 2; value <<= 2; modDiv <<= 2; } if (value < Long.MAX_VALUE / (1L << 1)) { exp -= 1; value <<= 1; modDiv <<= 1; } if (decimalPlaces > 1) value += modDiv * mod / 5; else value += (modDiv * mod + 4) / 5; } final double d = Math.scalb((double) value, exp); return negative ? -d : d; } private static void warnIdLimit(long id) { LOGGER.log(Level.WARNING, "High thread id may result in collisions id: " + id); ID_LIMIT_WARNED = true; } protected StringInterner stringInterner() { if (stringInterner == null) stringInterner = new StringInterner(8 * 1024); return stringInterner; } @Override public Boolean parseBoolean(@NotNull StopCharTester tester) { StringBuilder sb = acquireUtfReader(); parseUTF(sb, tester); if (sb.length() == 0) return null; switch (sb.charAt(0)) { case 't': case 'T': return sb.length() == 1 || equalsCaseIgnore(sb, "true") ? true : null; case 'y': case 'Y': return sb.length() == 1 || equalsCaseIgnore(sb, "yes") ? true : null; case '0': return sb.length() == 1 ? false : null; case '1': return sb.length() == 1 ? true : null; case 'f': case 'F': return sb.length() == 1 || equalsCaseIgnore(sb, "false") ? false : null; case 'n': case 'N': return sb.length() == 1 || equalsCaseIgnore(sb, "no") ? false : null; } return null; } @Override public void readFully(@NotNull byte[] bytes) { readFully(bytes, 0, bytes.length); } @Override public int skipBytes(int n) { long position = position(); int n2 = (int) Math.min(n, capacity() - position); position(position + n2); return n2; } @Override public boolean readBoolean() { return readByte() != 0; } @Override public boolean readBoolean(long offset) { return readByte(offset) != 0; } @Override public int readUnsignedByte() { return readByte() & UNSIGNED_BYTE_MASK; } @Override public int readUnsignedByte(long offset) { return readByte(offset) & UNSIGNED_BYTE_MASK; } @Override public int readUnsignedShort() { return readShort() & UNSIGNED_SHORT_MASK; } @Override public int readUnsignedShort(long offset) { return readShort(offset) & UNSIGNED_SHORT_MASK; } @NotNull @Override public String readLine() { StringBuilder input = acquireUtfReader(); EOL: while (position() < capacity()) { int c = readUnsignedByte(); switch (c) { case '\n': break EOL; case '\r': long cur = position(); if (cur < capacity() && readByte(cur) == '\n') position(cur + 1); break EOL; default: input.append((char) c); break; } } return stringInterner().intern(input); } @Nullable @Override public String readUTFΔ() { if (readUTFΔ(acquireUtfReader())) return utfReader.length() == 0 ? "" : stringInterner().intern(utfReader); return null; } @Nullable @Override public String readUTFΔ(long offset) throws IllegalStateException { long position = position(); try { position(offset); return readUTFΔ(); } finally { position(position); } } // RandomDataOutput @NotNull private StringBuilder acquireUtfReader() { if (utfReader == null) utfReader = new StringBuilder(); else utfReader.setLength(0); return utfReader; } @Override public boolean readUTFΔ(@NotNull StringBuilder stringBuilder) { try { stringBuilder.setLength(0); return appendUTF0(stringBuilder); } catch (IOException unexpected) { throw new IllegalStateException(unexpected); } } @SuppressWarnings("MagicNumber") private boolean appendUTF0(@NotNull Appendable appendable) throws IOException { long len = readStopBit(); if (len < -1 || len > Integer.MAX_VALUE) throw new StreamCorruptedException("UTF length invalid " + len); if (len == -1) return false; int utflen = (int) len; readUTF0(appendable, utflen); return true; } private void readUTF0(@NotNull Appendable appendable, int utflen) throws IOException { int count = 0; while (count < utflen) { int c = readByte(); if (c < 0) { position(position() - 1); break; } count++; appendable.append((char) c); } while (count < utflen) { int c = readUnsignedByte(); switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: /* 0xxxxxxx */ count++; appendable.append((char) c); break; case 12: case 13: { /* 110x xxxx 10xx xxxx */ count += 2; if (count > utflen) throw new UTFDataFormatException( "malformed input: partial character at end"); int char2 = readUnsignedByte(); if ((char2 & 0xC0) != 0x80) throw new UTFDataFormatException( "malformed input around byte " + count); int c2 = (char) (((c & 0x1F) << 6) | (char2 & 0x3F)); appendable.append((char) c2); break; } case 14: { /* 1110 xxxx 10xx xxxx 10xx xxxx */ count += 3; if (count > utflen) throw new UTFDataFormatException( "malformed input: partial character at end"); int char2 = readUnsignedByte(); int char3 = readUnsignedByte(); if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) throw new UTFDataFormatException( "malformed input around byte " + (count - 1)); int c3 = (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F)); appendable.append((char) c3); break; } default: /* 10xx xxxx, 1111 xxxx */ throw new UTFDataFormatException( "malformed input around byte " + count); } } } @NotNull @Override public String parseUTF(@NotNull StopCharTester tester) { parseUTF(acquireUtfReader(), tester); return stringInterner().intern(utfReader); } @Override public void parseUTF(@NotNull StringBuilder builder, @NotNull StopCharTester tester) { builder.setLength(0); try { readUTF0(builder, tester); } catch (IOException e) { throw new AssertionError(e); } } private void readUTF0(@NotNull Appendable appendable, @NotNull StopCharTester tester) throws IOException { while (remaining() > 0) { int c = readByte(); if (c < 0) { position(position() - 1); break; } if (tester.isStopChar(c)) return; appendable.append((char) c); } while (remaining() > 0) { int c = readUnsignedByte(); switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: /* 0xxxxxxx */ if (tester.isStopChar(c)) return; appendable.append((char) c); break; case 12: case 13: { /* 110x xxxx 10xx xxxx */ int char2 = readUnsignedByte(); if ((char2 & 0xC0) != 0x80) throw new UTFDataFormatException( "malformed input around byte"); int c2 = (char) (((c & 0x1F) << 6) | (char2 & 0x3F)); if (tester.isStopChar(c2)) return; appendable.append((char) c2); break; } case 14: { /* 1110 xxxx 10xx xxxx 10xx xxxx */ int char2 = readUnsignedByte(); int char3 = readUnsignedByte(); if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) throw new UTFDataFormatException( "malformed input around byte "); int c3 = (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | (char3 & 0x3F)); if (tester.isStopChar(c3)) return; appendable.append((char) c3); break; } default: /* 10xx xxxx, 1111 xxxx */ throw new UTFDataFormatException( "malformed input around byte "); } } } @Override public boolean stepBackAndSkipTo(@NotNull StopCharTester tester) { if (position() > 0) position(position() - 1); return skipTo(tester); } @Override public boolean skipTo(@NotNull StopCharTester tester) { while (remaining() > 0) { int ch = readByte(); if (tester.isStopChar(ch)) return true; } return false; } @NotNull @Override public String readUTF() { try { int len = readUnsignedShort(); readUTF0(acquireUtfReader(), len); return utfReader.length() == 0 ? "" : stringInterner().intern(utfReader); } catch (IOException unexpected) { throw new AssertionError(unexpected); } } @Override public short readCompactShort() { byte b = readByte(); switch (b) { case BYTE_MIN_VALUE: return Short.MIN_VALUE; case BYTE_MAX_VALUE: return Short.MAX_VALUE; case BYTE_EXTENDED: return readShort(); default: return b; } } @Override public int readCompactUnsignedShort() { int b = readUnsignedByte(); if (b == UBYTE_EXTENDED) return readUnsignedShort(); return b; } @Override public int readInt24() { int b = readUnsignedByte(); int s = readUnsignedShort(); if (byteOrder() == ByteOrder.BIG_ENDIAN) return ((b << 24) + (s << 8)) >> 8; // extra shifting to get sign extension. return ((b << 8) + (s << 16)) >> 8; } @Override public int readInt24(long offset) { int b = readUnsignedByte(offset); int s = readUnsignedShort(offset + 1); if (byteOrder() == ByteOrder.BIG_ENDIAN) return ((b << 24) + (s << 8)) >> 8; // extra shifting to get sign extension. return ((b << 8) + (s << 16)) >> 8; } @Override public long readUnsignedInt() { return readInt() & UNSIGNED_INT_MASK; } @Override public long readUnsignedInt(long offset) { return readInt(offset) & UNSIGNED_INT_MASK; } @Override public int readCompactInt() { short b = readShort(); switch (b) { case SHORT_MIN_VALUE: return Integer.MIN_VALUE; case SHORT_MAX_VALUE: return Integer.MAX_VALUE; case SHORT_EXTENDED: return readInt(); default: return b; } } @Override public long readCompactUnsignedInt() { int b = readUnsignedShort(); if (b == USHORT_EXTENDED) return readUnsignedInt(); return b; } @Override public long readInt48() { long s = readUnsignedShort(); long l = readUnsignedInt(); if (byteOrder() == ByteOrder.BIG_ENDIAN) return ((s << 48) + (l << 16)) >> 16; // extra shifting to get sign extension. return ((s << 16) + (l << 32)) >> 16; } @Override public long readInt48(long offset) { long s = readUnsignedShort(offset); long l = readUnsignedInt(offset + 2); if (byteOrder() == ByteOrder.BIG_ENDIAN) return ((s << 48) + (l << 16)) >> 16; // extra shifting to get sign extension. return ((s << 16) + (l << 32)) >> 16; } @Override public long readCompactLong() { int b = readInt(); switch (b) { case INT_MIN_VALUE: return Long.MIN_VALUE; case INT_MAX_VALUE: return Long.MAX_VALUE; case INT_EXTENDED: return readLong(); default: return b; } } @Override public long readStopBit() { long l = 0, b; int count = 0; while ((b = readByte()) < 0) { l |= (b & 0x7FL) << count; count += 7; } if (b == 0 && count > 0) return ~l; return l | (b << count); } @Override public double readCompactDouble() { float f = readFloat(); if (Float.isNaN(f)) return readDouble(); return f; } @Override public void read(@NotNull ByteBuffer bb) { int len = (int) Math.min(bb.remaining(), remaining()); if (bb.order() == byteOrder()) { while (len >= 8) { bb.putLong(readLong()); len -= 8; } } while (len > 0) { bb.put(readByte()); len--; } } // // RandomOutputStream @Override public void write(@NotNull byte[] bytes) { int length = bytes.length; checkWrite(length); write(bytes, 0, length); } private void checkWrite(int length) { if (length > remaining()) throw new IllegalStateException("Cannot write " + length + " only " + remaining() + " remaining"); } @Override public void writeBoolean(boolean v) { write(v ? -1 : 0); } @Override public void writeBoolean(long offset, boolean v) { writeByte(offset, v ? -1 : 0); } @Override public void writeBytes(@NotNull String s) { int len = s.length(); for (int i = 0; i < len; i++) write(s.charAt(i)); } @Override public void writeChars(@NotNull String s) { int len = s.length(); for (int i = 0; i < len; i++) writeChar(s.charAt(i)); } @Override public void writeUTF(@NotNull String str) { long strlen = str.length(); long utflen = findUTFLength(str, strlen); if (utflen > 65535) throw new IllegalStateException("String too long " + utflen + " when encoded, max: 65535"); writeUnsignedShort((int) utflen); writeUTF0(str, strlen); } @Override public void writeUTFΔ(@Nullable CharSequence str) { if (str == null) { writeStopBit(-1); return; } long strlen = str.length(); long utflen = findUTFLength(str, strlen); writeStopBit(utflen); writeUTF0(str, strlen); } @Override public void writeUTFΔ(long offset, int maxSize, @Nullable CharSequence s) throws IllegalStateException { assert maxSize > 1; if (s == null) { writeStopBit(-1); return; } long strlen = s.length(); long utflen = findUTFLength(s, strlen); long totalSize = IOTools.stopBitLength(utflen) + utflen; if (totalSize > maxSize) throw new IllegalStateException("Attempted to write " + totalSize + " byte String, when only " + maxSize + " allowed"); long position = position(); try { position(offset); writeStopBit(utflen); writeUTF0(s, strlen); } finally { position(position); } } @NotNull public ByteStringAppender append(@NotNull CharSequence str) { if (str == null) return this; long strlen = str.length(); writeUTF0(str, strlen); return this; } private long findUTFLength(@NotNull CharSequence str, long strlen) { long utflen = 0, c;/* use charAt instead of copying String to char array */ for (int i = 0; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0000) && (c <= 0x007F)) { utflen++; } else if (c > 0x07FF) { utflen += 3; } else { utflen += 2; } } if (utflen > remaining()) throw new IllegalArgumentException( "encoded string too long: " + utflen + " bytes, remaining=" + remaining()); return utflen; } private void writeUTF0(@NotNull CharSequence str, long strlen) { int c; int i; for (i = 0; i < strlen; i++) { c = str.charAt(i); if (!((c >= 0x0000) && (c <= 0x007F))) break; write(c); } for (; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0000) && (c <= 0x007F)) { write(c); } else if (c > 0x07FF) { write((byte) (0xE0 | ((c >> 12) & 0x0F))); write((byte) (0x80 | ((c >> 6) & 0x3F))); write((byte) (0x80 | (c & 0x3F))); } else { write((byte) (0xC0 | ((c >> 6) & 0x1F))); write((byte) (0x80 | c & 0x3F)); } } } @Override public void writeByte(int v) { write(v); } @Override public void writeUnsignedByte(int v) { writeByte(v); } @Override public void writeUnsignedByte(long offset, int v) { writeByte(offset, v); } @Override public void write(long offset, @NotNull byte[] bytes) { checkWrite(bytes.length); for (int i = 0; i < bytes.length; i++) writeByte(offset + i, bytes[i]); } @Override public void write(byte[] bytes, int off, int len) { checkWrite(bytes.length); for (int i = 0; i < len; i++) write(bytes[off + i]); } @Override public void writeUnsignedShort(int v) { writeShort(v); } @Override public void writeUnsignedShort(long offset, int v) { writeShort(offset, v); } @Override public void writeCompactShort(int v) { if (v > BYTE_MAX_VALUE && v <= Byte.MAX_VALUE) writeByte(v); else switch (v) { case Short.MIN_VALUE: writeByte(BYTE_MIN_VALUE); break; case Short.MAX_VALUE: writeByte(BYTE_MAX_VALUE); break; default: writeByte(BYTE_EXTENDED); writeShort(v); break; } } @Override public void writeCompactUnsignedShort(int v) { if (v >= 0 && v < USHORT_EXTENDED) { writeByte(v); } else { writeUnsignedShort(USHORT_EXTENDED); writeUnsignedShort(v); } } @Override public void writeInt24(int v) { if (byteOrder() == ByteOrder.BIG_ENDIAN) { writeUnsignedByte(v >>> 16); writeUnsignedShort(v); } else { writeUnsignedByte(v); writeUnsignedShort(v >>> 8); } } @Override public void writeInt24(long offset, int v) { if (byteOrder() == ByteOrder.BIG_ENDIAN) { writeUnsignedByte(offset, v >>> 16); writeUnsignedShort(offset + 1, v); } else { writeUnsignedByte(offset, v); writeUnsignedShort(offset + 1, v >>> 8); } } @Override public void writeUnsignedInt(long v) { writeInt((int) v); } @Override public void writeUnsignedInt(long offset, long v) { writeInt(offset, (int) v); } @Override public void writeCompactInt(int v) { if (v > SHORT_MAX_VALUE && v <= Short.MAX_VALUE) writeShort(v); else switch (v) { case Integer.MIN_VALUE: writeShort(SHORT_MIN_VALUE); break; case Integer.MAX_VALUE: writeShort(SHORT_MAX_VALUE); break; default: writeShort(SHORT_EXTENDED); writeInt(v); break; } } @Override public void writeCompactUnsignedInt(long v) { if (v >= 0 && v < USHORT_EXTENDED) { writeShort((int) v); } else { writeShort(USHORT_EXTENDED); writeUnsignedInt(v); } } @Override public void writeInt48(long v) { if (byteOrder() == ByteOrder.BIG_ENDIAN) { writeUnsignedShort((int) (v >>> 32)); writeUnsignedInt(v); } else { writeUnsignedShort((int) v); writeUnsignedInt(v >>> 16); } } @Override public void writeInt48(long offset, long v) { if (byteOrder() == ByteOrder.BIG_ENDIAN) { writeUnsignedShort(offset, (int) (v >>> 32)); writeUnsignedInt(offset + 2, v); } else { writeUnsignedShort(offset, (int) v); writeUnsignedInt(offset + 2, v >>> 16); } } @Override public void writeCompactLong(long v) { if (v > INT_MAX_VALUE && v <= Integer.MAX_VALUE) { writeInt((int) v); } else if (v == Long.MIN_VALUE) { writeInt(INT_MIN_VALUE); } else if (v == Long.MAX_VALUE) { writeInt(INT_MAX_VALUE); } else { writeInt(INT_EXTENDED); writeLong(v); } } @Override public void writeStopBit(long n) { boolean neg = false; if (n < 0) { neg = true; n = ~n; } while (true) { long n2 = n >>> 7; if (n2 != 0) { writeByte((byte) (0x80 | (n & 0x7F))); n = n2; } else { if (neg) { writeByte((byte) (0x80 | (n & 0x7F))); writeByte(0); } else { writeByte((byte) (n & 0x7F)); } break; } } } @Override public void writeCompactDouble(double v) { float f = (float) v; if (f == v) { writeFloat(f); } else { writeFloat(Float.NaN); writeDouble(v); } } @Override public void write(@NotNull ByteBuffer bb) { if (bb.order() == byteOrder()) while (bb.remaining() >= 8) writeLong(bb.getLong()); while (bb.remaining() >= 1) writeByte(bb.get()); } @Deprecated @Override public void writeStartToPosition(@NotNull Bytes bb) { final long position = bb.position(); long offset = 0; if (position > remaining()) throw new IndexOutOfBoundsException("Trying to write " + position + " when only " + remaining() + " left"); // TODO optimise this to use Unsafe copy memory while (position - offset >= 8) { writeLong(bb.readLong(offset)); offset += 8; } while (position - offset >= 1) writeByte(bb.readByte(offset++)); } // // ByteStringAppender @NotNull @Override public ByteStringAppender append(@NotNull CharSequence s, int start, int end) { for (int i = start, len = Math.min(end, s.length()); i < len; i++) writeByte(s.charAt(i)); return this; } @NotNull @Override public ByteStringAppender append(@Nullable Enum value) { return value == null ? this : append(value.toString()); } @NotNull @Override public ByteStringAppender append(boolean b) { append(b ? "true" : "false"); return this; } @NotNull @Override public ByteStringAppender append(char c) { writeByte(c); return this; } @NotNull @Override public ByteStringAppender append(int num) { return append((long) num); } @NotNull @Override public ByteStringAppender append(long num) { if (num < 0) { if (num == Long.MIN_VALUE) { write(MIN_VALUE_TEXT); return this; } writeByte('-'); num = -num; } if (num == 0) { writeByte('0'); } else { appendLong0(num); } return this; } @NotNull @Override public ByteStringAppender append(long num, int base) { if (base < 2 || base > Character.MAX_RADIX) throw new IllegalArgumentException("Invalid base: " + base); if (num < 0) { if (num == Long.MIN_VALUE) { writeBytes(BigInteger.valueOf(num).toString(base)); return this; } writeByte('-'); num = -num; } if (num == 0) { writeByte('0'); } else { while (num > 0) { writeByte(RADIX[((int) (num % base))]); num /= base; } } return this; } @NotNull @Override public ByteStringAppender appendDateMillis(long timeInMS) { if (dateFormat == null) { dateFormat = new SimpleDateFormat("yyyy/MM/dd"); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); } long date = timeInMS / 86400000; if (lastDay != date) { lastDateStr = dateFormat.format(new Date(timeInMS)).getBytes(ISO_8859_1); lastDay = date; } else { assert lastDateStr != null; } write(lastDateStr); return this; } @NotNull @Override public ByteStringAppender appendDateTimeMillis(long timeInMS) { appendDateMillis(timeInMS); writeByte('T'); appendTimeMillis(timeInMS % 86400000L); return this; } @NotNull @Override public ByteStringAppender appendTimeMillis(long timeInMS) { int hours = (int) (timeInMS / (60 * 60 * 1000)); if (hours > 99) { appendLong0(hours); // can have over 24 hours. } else { writeByte((char) (hours / 10 + '0')); writeByte((char) (hours % 10 + '0')); } writeByte(':'); int minutes = (int) ((timeInMS / (60 * 1000)) % 60); writeByte((char) (minutes / 10 + '0')); writeByte((char) (minutes % 10 + '0')); writeByte(':'); int seconds = (int) ((timeInMS / 1000) % 60); writeByte((char) (seconds / 10 + '0')); writeByte((char) (seconds % 10 + '0')); writeByte('.'); int millis = (int) (timeInMS % 1000); writeByte((char) (millis / 100 + '0')); writeByte((char) (millis / 10 % 10 + '0')); writeByte((char) (millis % 10 + '0')); return this; } @NotNull @Override public ByteStringAppender append(double d) { long val = Double.doubleToRawLongBits(d); int sign = (int) (val >>> 63); int exp = (int) ((val >>> 52) & 2047); long mantissa = val & ((1L << 52) - 1); if (sign != 0) { writeByte('-'); } if (exp == 0 && mantissa == 0) { writeByte('0'); return this; } else if (exp == 2047) { if (mantissa == 0) { write(Infinity); } else { write(NaN); } return this; } else if (exp > 0) { mantissa += 1L << 52; } final int shift = (1023 + 52) - exp; if (shift > 0) { // integer and faction if (shift < 53) { long intValue = mantissa >> shift; appendLong0(intValue); mantissa -= intValue << shift; if (mantissa > 0) { writeByte('.'); mantissa <<= 1; mantissa++; int precision = shift + 1; long error = 1; long value = intValue; int decimalPlaces = 0; while (mantissa > error) { // times 5*2 = 10 mantissa *= 5; error *= 5; precision--; long num = (mantissa >> precision); value = value * 10 + num; writeByte((char) ('0' + num)); mantissa -= num << precision; final double parsedValue = asDouble(value, 0, sign != 0, ++decimalPlaces); if (parsedValue == d) break; } } return this; } else { // faction. writeByte('0'); writeByte('.'); mantissa <<= 6; mantissa += (1 << 5); int precision = shift + 6; long error = (1 << 5); long value = 0; int decimalPlaces = 0; while (mantissa > error) { while (mantissa > MAX_VALUE_DIVIDE_5) { mantissa >>>= 1; error = (error + 1) >>> 1; precision--; } // times 5*2 = 10 mantissa *= 5; error *= 5; precision--; if (precision >= 64) { decimalPlaces++; writeByte('0'); continue; } long num = (mantissa >>> precision); value = value * 10 + num; final char c = (char) ('0' + num); assert !(c < '0' || c > '9'); writeByte(c); mantissa -= num << precision; final double parsedValue = asDouble(value, 0, sign != 0, ++decimalPlaces); if (parsedValue == d) break; } return this; } } // large number mantissa <<= 10; int precision = -10 - shift; int digits = 0; while ((precision > 53 || mantissa > Long.MAX_VALUE >> precision) && precision > 0) { digits++; precision--; long mod = mantissa % 5; mantissa /= 5; int modDiv = 1; while (mantissa < MAX_VALUE_DIVIDE_5 && precision > 1) { precision -= 1; mantissa <<= 1; modDiv <<= 1; } mantissa += modDiv * mod / 5; } long val2 = precision > 0 ? mantissa << precision : mantissa >>> -precision; appendLong0(val2); for (int i = 0; i < digits; i++) writeByte('0'); return this; } @Override public double parseDouble() { long value = 0; int exp = 0; boolean negative = false; int decimalPlaces = Integer.MIN_VALUE; while (true) { byte ch = readByte(); if (ch >= '0' && ch <= '9') { while (value >= MAX_VALUE_DIVIDE_10) { value >>>= 1; exp++; } value = value * 10 + (ch - '0'); decimalPlaces++; } else if (ch == '-') { negative = true; } else if (ch == '.') { decimalPlaces = 0; } else { break; } } return asDouble(value, exp, negative, decimalPlaces); } @NotNull @Override public ByteStringAppender append(@NotNull Iterable list, @NotNull CharSequence separator) { if (list instanceof RandomAccess && list instanceof List) { return append((List) list, separator); } int i = 0; for (E e : list) { if (i++ > 0) append(separator); if (e != null) append(e.toString()); } return this; } @NotNull public ByteStringAppender append(@NotNull List list, @NotNull CharSequence separator) { for (int i = 0; i < list.size(); i++) { if (i > 0) append(separator); E e = list.get(i); if (e != null) append(e.toString()); } return this; } @NotNull @Override public MutableDecimal parseDecimal(@NotNull MutableDecimal decimal) { long num = 0, scale = Long.MIN_VALUE; boolean negative = false; while (true) { byte b = readByte(); // if (b >= '0' && b <= '9') if ((b - ('0' + Integer.MIN_VALUE)) <= 9 + Integer.MIN_VALUE) { num = num * 10 + b - '0'; scale++; } else if (b == '.') { scale = 0; } else if (b == '-') { negative = true; } else { break; } } if (negative) num = -num; decimal.set(num, scale > 0 ? (int) scale : 0); return decimal; } @Override public long parseLong() { long num = 0; boolean negative = false; while (true) { byte b = readByte(); // if (b >= '0' && b <= '9') if ((b - ('0' + Integer.MIN_VALUE)) <= 9 + Integer.MIN_VALUE) num = num * 10 + b - '0'; else if (b == '-') negative = true; else break; } return negative ? -num : num; } @Override public long parseLong(int base) { if (base < 2 || base > Character.MAX_RADIX) throw new IllegalArgumentException("Invalid base:" + base); long num = 0; boolean negative = false; while (true) { byte b = readByte(); byte rp = RADIX_PARSE[b]; if (rp >= 0 && rp < base) { num = num * base + rp; } else if (b == '-') negative = true; else break; } return negative ? -num : num; } private void appendLong0(long num) { // Extract digits into the end of the numberBuffer int endIndex = appendLong1(num); // Bulk copy the digits into the front of the buffer write(numberBuffer, endIndex, MAX_NUMBER_LENGTH - endIndex); } private int appendLong1(long num) { numberBuffer[19] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 19; numberBuffer[18] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 18; numberBuffer[17] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 17; numberBuffer[16] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 16; numberBuffer[15] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 15; numberBuffer[14] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 14; numberBuffer[13] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 13; numberBuffer[12] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 12; numberBuffer[11] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 11; numberBuffer[10] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 10; numberBuffer[9] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 9; numberBuffer[8] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 8; numberBuffer[7] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 7; numberBuffer[6] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 6; numberBuffer[5] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 5; numberBuffer[4] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 4; numberBuffer[3] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 3; numberBuffer[2] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0) return 2; numberBuffer[1] = (byte) (num % 10L + '0'); num /= 10; return 1; } @NotNull @Override public ByteStringAppender append(double d, int precision) { if (precision < 0) precision = 0; long power10 = Maths.power10(precision); if (power10 < 0) power10 = 100000000000000000L; if (d < 0) { d = -d; writeByte('-'); } double d2 = d * power10; if (d2 > Long.MAX_VALUE || d2 < Long.MIN_VALUE + 1) return append(d); long val = (long) (d2 + 0.5); while (precision > 1 && val % 10 == 0) { val /= 10; precision--; } if (precision > 0 && val % 10 == 0) { val = (val + 5) / 10; precision--; } if (precision > 0) appendDouble0(val, precision); else appendLong0(val); return this; } private void appendDouble0(long num, int precision) { // Extract digits into the end of the numberBuffer // Once desired precision is reached, write the '.' int endIndex = appendDouble1(num, precision); // Bulk copy the digits into the front of the buffer // TODO: Can this be avoided with use of correctly offset bulk appends on Excerpt? // Uses (numberBufferIdx - 1) because index was advanced one too many times write(numberBuffer, endIndex, MAX_NUMBER_LENGTH - endIndex); } private int appendDouble1(long num, int precision) { int endIndex = MAX_NUMBER_LENGTH; int maxEnd = MAX_NUMBER_LENGTH - precision - 2; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 1) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 2) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 3) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 4) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 5) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 6) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 7) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 8) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 9) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 10) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 11) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 12) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 13) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 14) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 15) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 16) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 17) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); num /= 10; if (num <= 0 && endIndex <= maxEnd) return endIndex; if (precision == 18) numberBuffer[--endIndex] = (byte) '.'; numberBuffer[--endIndex] = (byte) (num % 10L + '0'); return endIndex; } @NotNull @Override public ByteStringAppender append(@NotNull MutableDecimal md) { StringBuilder sb = acquireUtfReader(); md.toString(sb); append(sb); return this; } @NotNull @Override public InputStream inputStream() { if (inputStream == null) inputStream = new BytesInputStream(); return inputStream; } @NotNull @Override public OutputStream outputStream() { if (outputStream == null) outputStream = new BytesOutputStream(); return outputStream; } @NotNull @Override public BytesMarshallerFactory bytesMarshallerFactory() { return bytesMarshallerFactory == null ? bytesMarshallerFactory = new VanillaBytesMarshallerFactory() : bytesMarshallerFactory; } @SuppressWarnings("unchecked") @Override public void writeEnum(@Nullable E e) { Class aClass; if (e == null || e instanceof CharSequence) aClass = String.class; else aClass = (Class) e.getClass(); BytesMarshaller em = bytesMarshallerFactory().acquireMarshaller(aClass, true); em.write(this, e); } @SuppressWarnings("unchecked") @Override public E readEnum(@NotNull Class eClass) { BytesMarshaller em = bytesMarshallerFactory().acquireMarshaller(eClass, true); return em.read(this); } @SuppressWarnings("unchecked") @Override public > E parseEnum(@NotNull Class eClass, @NotNull StopCharTester tester) { String text = parseUTF(tester); if (text.isEmpty()) return null; return Enum.valueOf(eClass, text); } @Override public void writeList(@NotNull Collection list) { writeStopBit(list.size()); for (E e : list) writeEnum(e); } @Override public void writeMap(@NotNull Map map) { writeStopBit(map.size()); for (Map.Entry entry : map.entrySet()) { writeEnum(entry.getKey()); writeEnum(entry.getValue()); } } @Override public void readList(@NotNull Collection list, @NotNull Class eClass) { int len = (int) readStopBit(); list.clear(); for (int i = 0; i < len; i++) { @SuppressWarnings("unchecked") E e = (E) readEnum(eClass); list.add(e); } } @Override @NotNull public Map readMap(@NotNull Map map, @NotNull Class kClass, @NotNull Class vClass) { int len = (int) readStopBit(); map.clear(); for (int i = 0; i < len; i++) map.put(readEnum(kClass), readEnum(vClass)); return map; } @Override public int available() { return (int) Math.min(Integer.MAX_VALUE, remaining()); } @Override public int read() { return remaining() > 0 ? readByte() : -1; } @Override public int read(@NotNull byte[] bytes) { return read(bytes, 0, bytes.length); } @Override public abstract int read(@NotNull byte[] bytes, int off, int len); @Override public long skip(long n) { if (n < 0) throw new IllegalArgumentException("Skip bytes out of range, was " + n); if (n > remaining()) n = remaining(); skipBytes((int) n); return n; } @Override public void close() { if (!isFinished()) finish(); } @Override public void finish() throws IndexOutOfBoundsException { if (remaining() < 0) throwOverflow(); finished = true; } private void throwOverflow() throws IndexOutOfBoundsException { throw new IndexOutOfBoundsException("Buffer overflow, capacity: " + capacity() + " position: " + position()); } @Override public boolean isFinished() { return finished; } @Override public void reset() { finished = false; position(0L); } @Override public void flush() { checkEndOfBuffer(); } @Nullable @Override public Object readObject() { byte type = readByte(); switch (type) { case NULL: return null; case ENUMED: { Class clazz = readEnum(Class.class); return readEnum(clazz); } case SERIALIZED: { try { return new ObjectInputStream(this.inputStream()).readObject(); } catch (Exception e) { throw new IllegalStateException(e); } } default: BytesMarshaller m = bytesMarshallerFactory().getMarshaller(type); if (m == null) throw new IllegalStateException("Unknown type " + (char) type); return m.read(this); } } @Nullable @Override public T readObject(Class tClass) throws IllegalStateException { Object o = readObject(); if (o == null || tClass.isInstance(o)) return (T) o; throw new ClassCastException("Cannot convert " + o.getClass().getName() + " to " + tClass.getName() + " was " + o); } @SuppressWarnings("unchecked") @Override public void writeObject(@Nullable Object obj) { if (obj == null) { writeByte(NULL); return; } Class clazz = obj.getClass(); final BytesMarshallerFactory bytesMarshallerFactory = bytesMarshallerFactory(); BytesMarshaller em = bytesMarshallerFactory.acquireMarshaller(clazz, false); if (em == NoMarshaller.INSTANCE && autoGenerateMarshaller(obj)) em = bytesMarshallerFactory.acquireMarshaller(clazz, true); if (em != NoMarshaller.INSTANCE) { if (em instanceof CompactBytesMarshaller) { writeByte(((CompactBytesMarshaller) em).code()); em.write(this, obj); return; } writeByte(ENUMED); writeEnum(clazz); em.write(this, obj); return; } writeByte(SERIALIZED); // TODO this is the lame implementation, but it works. try { ObjectOutputStream oos = new ObjectOutputStream(this.outputStream()); oos.writeObject(obj); } catch (IOException e) { throw new IllegalStateException(e); } checkEndOfBuffer(); } protected boolean autoGenerateMarshaller(Object obj) { return (obj instanceof Comparable && obj.getClass().getPackage().getName().startsWith("java")) || obj instanceof Externalizable || obj instanceof BytesMarshallable; } @Override public boolean tryLockInt(long offset) { long id = shortThreadId(); return tryLockNanos4a(offset, (int) id); } @Override public boolean tryLockNanosInt(long offset, long nanos) { long id = shortThreadId(); int limit = nanos <= 10000 ? (int) nanos / 10 : 1000; for (int i = 0; i < limit; i++) if (tryLockNanos4a(offset, (int) id)) return true; if (nanos <= 10000) return false; long end = System.nanoTime() + nanos - 10000; do { if (tryLockNanos4a(offset, (int) id)) return true; } while (end > System.nanoTime() && !currentThread().isInterrupted()); return false; } private boolean tryLockNanos4a(long offset, int id) { int lowId = shortThreadId(); int firstValue = ((1 << 24) | lowId); if (compareAndSwapInt(offset, 0, firstValue)) return true; long currentValue = readUnsignedInt(offset); if ((currentValue & INT_LOCK_MASK) == lowId) { if (currentValue >= (255L << 24)) throw new IllegalStateException("Reentred 255 times without an unlock"); currentValue += 1 << 24; writeOrderedInt(offset, (int) currentValue); } return false; } @Override public void busyLockInt(long offset) throws InterruptedException, IllegalStateException { boolean success = tryLockNanosInt(offset, BUSY_LOCK_LIMIT); if (!success) if (currentThread().isInterrupted()) throw new InterruptedException(); else throw new IllegalStateException("Failed to acquire lock after " + BUSY_LOCK_LIMIT / 1e9 + " seconds."); } @Override public void unlockInt(long offset) throws IllegalMonitorStateException { int lowId = shortThreadId(); int firstValue = ((1 << 24) | lowId); if (compareAndSwapInt(offset, firstValue, 0)) return; // try to chek the lowId and the count. unlockFailedInt(offset, lowId); } private Thread currentThread; private int shortThreadId = Integer.MIN_VALUE; public int shortThreadId() { return shortThreadId > 0 ? shortThreadId : shortThreadId0(); } protected int shortThreadId0() { final int tid = (int) getId() & INT_LOCK_MASK; if (!ID_LIMIT_WARNED && tid > 1 << 24) { warnIdLimit(tid); } return tid; } public void setCurrentThread() { currentThread = Thread.currentThread(); shortThreadId = shortThreadId0(); } public Thread currentThread() { return currentThread == null ? Thread.currentThread() : currentThread; } @Override public boolean tryLockLong(long offset) { long id = uniqueTid(); return tryLockNanos8a(offset, id); } public long uniqueTid() { return Jvm.getUniqueTid(currentThread()); } @Override public boolean tryLockNanosLong(long offset, long nanos) { long id = uniqueTid(); int limit = nanos <= 10000 ? (int) nanos / 10 : 1000; for (int i = 0; i < limit; i++) if (tryLockNanos8a(offset, id)) return true; if (nanos <= 10000) return false; long end = System.nanoTime() + nanos - 10000; do { if (tryLockNanos8a(offset, id)) return true; } while (end > System.nanoTime() && !currentThread().isInterrupted()); return false; } private boolean tryLockNanos8a(long offset, long id) { long firstValue = (1L << 48) | id; if (compareAndSwapLong(offset, 0, firstValue)) return true; long currentValue = readLong(offset); if ((currentValue & (1L << 48) - 1) == id) { if (currentValue >>> 48 == 65535) throw new IllegalStateException("Reentred 65535 times without an unlock"); currentValue += 1L << 48; writeOrderedLong(offset, currentValue); return true; } return false; } @Override public void busyLockLong(long offset) throws InterruptedException, IllegalStateException { boolean success = tryLockNanosLong(offset, BUSY_LOCK_LIMIT); if (!success) if (currentThread().isInterrupted()) throw new InterruptedException(); else throw new IllegalStateException("Failed to acquire lock after " + BUSY_LOCK_LIMIT / 1e9 + " seconds."); } @Override public void unlockLong(long offset) throws IllegalMonitorStateException { long id = Jvm.getUniqueTid(); long firstValue = (1L << 48) | id; if (compareAndSwapLong(offset, firstValue, 0)) return; // try to check the lowId and the count. unlockFailedLong(offset, id); } protected long getId() { return currentThread().getId(); } private void unlockFailedInt(long offset, int lowId) throws IllegalMonitorStateException { long currentValue = readUnsignedInt(offset); long holderId = currentValue & INT_LOCK_MASK; if (holderId == lowId) { currentValue -= 1 << 24; writeOrderedInt(offset, (int) currentValue); } else if (currentValue == 0) { throw new IllegalMonitorStateException("No thread holds this lock"); } else { throw new IllegalMonitorStateException("Thread " + holderId + " holds this lock, " + (currentValue >>> 24) + " times"); } } private void unlockFailedLong(long offset, long id) throws IllegalMonitorStateException { long currentValue = readLong(offset); long holderId = currentValue & (-1L >>> 16); if (holderId == id) { currentValue -= 1L << 48; writeOrderedLong(offset, currentValue); } else if (currentValue == 0) { throw new IllegalMonitorStateException("No thread holds this lock"); } else { throw new IllegalMonitorStateException("Process " + ((currentValue >>> 32) & 0xFFFF) + " thread " + (holderId & (-1L >>> 32)) + " holds this lock, " + (currentValue >>> 48) + " times, unlock from " + Jvm.getProcessId() + " thread " + currentThread().getId()); } } @Override public int getAndAdd(long offset, int delta) { for (; ; ) { int current = readVolatileInt(offset); int next = current + delta; if (compareAndSwapInt(offset, current, next)) return current; } } @Override public int addAndGetInt(long offset, int delta) { for (; ; ) { int current = readVolatileInt(offset); int next = current + delta; if (compareAndSwapInt(offset, current, next)) return next; } } @Override public byte addByte(long offset, byte b) { byte b2 = readByte(offset); b2 += b; writeByte(offset, b2); return b2; } @Override public int addUnsignedByte(long offset, int i) { int b2 = readUnsignedByte(offset); b2 += i; writeUnsignedByte(offset, b2); return b2 & 0xFF; } @Override public short addShort(long offset, short s) { short s2 = readShort(offset); s2 += s; writeByte(offset, s2); return s2; } @Override public int addUnsignedShort(long offset, int i) { int b2 = readUnsignedShort(offset); b2 += i; writeUnsignedShort(offset, b2); return b2 & 0xFFFF; } @Override public int addInt(long offset, int i) { int b2 = readInt(offset); b2 += i; writeInt(offset, b2); return b2; } @Override public long addUnsignedInt(long offset, long i) { long b2 = readUnsignedInt(offset); b2 += i; writeUnsignedInt(offset, b2); return b2 & 0xFFFFFFFFL; } @Override public long addLong(long offset, long i) { long b2 = readLong(offset); b2 += i; writeLong(offset, b2); return b2; } @Override public float addFloat(long offset, float f) { float b2 = readFloat(offset); b2 += f; writeFloat(offset, b2); return b2; } @Override public double addDouble(long offset, double d) { double b2 = readDouble(offset); b2 += d; writeDouble(offset, b2); return b2; } @Override public int addAtomicInt(long offset, int i) { return addAndGetInt(offset, i); } @Override public long addAtomicLong(long offset, long delta) { for (; ; ) { long current = readVolatileLong(offset); long next = current + delta; if (compareAndSwapLong(offset, current, next)) return next; } } @Override public float addAtomicFloat(long offset, float delta) { for (; ; ) { int current = readVolatileInt(offset); int next = Float.floatToRawIntBits(Float.intBitsToFloat(current) + delta); if (compareAndSwapInt(offset, current, next)) return next; } } @Override public double addAtomicDouble(long offset, double delta) { for (; ; ) { long current = readVolatileLong(offset); long next = Double.doubleToRawLongBits(Double.longBitsToDouble(current) + delta); if (compareAndSwapLong(offset, current, next)) return next; } } @Override public float readVolatileFloat(long offset) { return Float.intBitsToFloat(readVolatileInt(offset)); } @Override public double readVolatileDouble(long offset) { return Double.longBitsToDouble(readVolatileLong(offset)); } @Override public void writeOrderedFloat(long offset, float v) { writeOrderedInt(offset, Float.floatToRawIntBits(v)); } @Override public void writeOrderedDouble(long offset, double v) { writeOrderedLong(offset, Double.doubleToRawLongBits(v)); } @Override public int length() { return (int) Math.min(Integer.MAX_VALUE, remaining()); } @Override public char charAt(int index) { return (char) readUnsignedByte(index); } @Override public CharSequence subSequence(int start, int end) { StringBuilder sb = new StringBuilder(end - start + 1); for (int i = start; i < end; i++) sb.append(charAt(i)); return sb; } @Override public void readMarshallable(@NotNull Bytes in) throws IllegalStateException { long len = Math.min(remaining(), in.remaining()); long inPosition = in.position(); write(in, inPosition, len); in.position(inPosition + len); } @Override public void writeMarshallable(@NotNull Bytes out) { out.write(this, position(), remaining()); } @Override public void write(BytesCommon bytes, long position, long length) { if (length > bytes.remaining()) throw new IllegalArgumentException("Attempt to write " + length + " bytes with " + remaining() + " remaining"); RandomDataInput rdi = (RandomDataInput) bytes; if (bytes.byteOrder() == byteOrder()) { while (length >= 8) { writeLong(rdi.readLong(position)); position += 8; length -= 8; } } while (length >= 1) { writeByte(rdi.readByte(position)); position++; length--; } } protected class BytesInputStream extends InputStream { private long mark = 0; @Override public int available() throws IOException { long remaining = remaining(); return (int) Math.min(Integer.MAX_VALUE, remaining); } @Override public void close() throws IOException { finish(); } @SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") @Override public void mark(int readlimit) { mark = position(); } @Override public boolean markSupported() { return true; } @Override public int read(byte[] b, int off, int len) throws IOException { return AbstractBytes.this.read(b, off, len); } @SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") @Override public void reset() throws IOException { position(mark); } @Override public long skip(long n) throws IOException { if (n > Integer.MAX_VALUE) throw new IOException("Skip too large"); return skipBytes((int) n); } @Override public int read() throws IOException { if (remaining() > 0) return readUnsignedByte(); return -1; } } protected class BytesOutputStream extends OutputStream { @Override public void close() throws IOException { finish(); } @Override public void write(@NotNull byte[] b) throws IOException { AbstractBytes.this.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { AbstractBytes.this.write(b, off, len); } @Override public void write(int b) throws IOException { checkWrite(1); writeUnsignedByte(b); } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/ByteBufferBytes.java000077500000000000000000000266761226752375100263650ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import sun.nio.ch.DirectBuffer; import java.io.EOFException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.concurrent.atomic.AtomicBoolean; /** * @author peter.lawrey */ public class ByteBufferBytes extends AbstractBytes { protected final ByteBuffer buffer; protected int start, position, limit; protected AtomicBoolean barrier; public ByteBufferBytes(ByteBuffer buffer) { this(buffer, 0, buffer.capacity()); } public ByteBufferBytes(ByteBuffer buffer, int start, int limit) { this.buffer = buffer; this.start = position = start; this.limit = limit; } public ByteBuffer buffer() { return buffer; } protected void readBarrier() { if (barrier == null) barrier = new AtomicBoolean(); barrier.get(); } protected void writeBarrier() { if (barrier == null) barrier = new AtomicBoolean(); barrier.lazySet(false); } @Override public int read(@NotNull byte[] bytes, int off, int len) { if (len < 0 || off < 0 || off + len > bytes.length) throw new IllegalArgumentException(); long left = remaining(); if (left <= 0) return -1; int len2 = (int) Math.min(left, len); for (int i = 0; i < len2; i++) bytes[off + i] = readByte(); return len2; } @Override public byte readByte() { if (position < limit) return buffer.get(position++); throw new IndexOutOfBoundsException(); } @Override public byte readByte(long offset) { int pos = (int) (start + offset); if (pos < limit) return buffer.get(pos); throw new IndexOutOfBoundsException(); } @Override public void readFully(@NotNull byte[] b, int off, int len) { if (len < 0 || off < 0 || off + len > b.length) throw new IllegalArgumentException(); long left = remaining(); if (left < len) throw new IllegalStateException(new EOFException()); for (int i = 0; i < len; i++) b[off + i] = readByte(); } @Override public short readShort() { if (position + 2 <= limit) { short s = buffer.getShort(position); position += 2; return s; } throw new IndexOutOfBoundsException(); } @Override public short readShort(long offset) { int pos = (int) (start + offset); if (pos + 2 <= limit) return buffer.getShort(pos); throw new IndexOutOfBoundsException(); } @Override public char readChar() { if (position + 2 <= limit) { char ch = buffer.getChar(position); position += 2; return ch; } throw new IndexOutOfBoundsException(); } @Override public char readChar(long offset) { int pos = (int) (start + offset); if (pos + 2 <= limit) return buffer.getChar(pos); throw new IndexOutOfBoundsException(); } @Override public int readInt() { if (position + 4 <= limit) { int i = buffer.getInt(position); position += 4; return i; } throw new IndexOutOfBoundsException(); } @Override public int readInt(long offset) { int pos = (int) (start + offset); if (pos + 4 <= limit) return buffer.getInt(pos); throw new IndexOutOfBoundsException(); } @Override public int readVolatileInt() { readBarrier(); return readInt(); } @Override public int readVolatileInt(long offset) { readBarrier(); return readInt(offset); } @Override public long readLong() { if (position + 8 <= limit) { long l = buffer.getLong(position); position += 8; return l; } throw new IndexOutOfBoundsException(); } @Override public long readLong(long offset) { int pos = (int) (start + offset); if (pos + 8 <= limit) return buffer.getLong(pos); throw new IndexOutOfBoundsException(); } @Override public long readVolatileLong() { readBarrier(); return readLong(); } @Override public long readVolatileLong(long offset) { readBarrier(); return readLong(offset); } @Override public float readFloat() { if (position + 4 <= limit) { float f = buffer.getFloat(position); position += 4; return f; } throw new IndexOutOfBoundsException(); } @Override public float readFloat(long offset) { int pos = (int) (start + offset); if (pos + 4 <= limit) return buffer.getFloat(pos); throw new IndexOutOfBoundsException(); } @Override public double readDouble() { if (position + 8 <= limit) { double d = buffer.getDouble(position); position += 8; return d; } throw new IndexOutOfBoundsException(); } @Override public double readDouble(long offset) { int pos = (int) (start + offset); if (pos + 8 <= limit) return buffer.getDouble(pos); throw new IndexOutOfBoundsException(); } @Override public void write(int b) { if (position < limit) buffer.put(position++, (byte) b); else throw new IndexOutOfBoundsException(); } @Override public void writeByte(long offset, int b) { int pos = (int) (start + offset); if (pos < limit) buffer.put(pos, (byte) b); else throw new IndexOutOfBoundsException(); } @Override public void writeShort(int v) { if (position + 2 <= limit) { buffer.putShort(position, (short) v); position += 2; } else { throw new IndexOutOfBoundsException(); } } @Override public void writeShort(long offset, int v) { int pos = (int) (start + offset); if (pos + 2 <= limit) buffer.putShort(pos, (short) v); else throw new IndexOutOfBoundsException(); } @Override public void writeChar(int v) { if (position + 2 <= limit) { buffer.putChar(position, (char) v); position += 2; } else { throw new IndexOutOfBoundsException(); } } @Override public void writeChar(long offset, int v) { int pos = (int) (start + offset); if (pos + 2 <= limit) buffer.putChar(pos, (char) v); else throw new IndexOutOfBoundsException(); } @Override public void writeInt(int v) { if (position + 4 <= limit) { buffer.putInt(position, v); position += 4; } else { throw new IndexOutOfBoundsException(); } } @Override public void writeInt(long offset, int v) { int pos = (int) (start + offset); if (pos + 4 <= limit) buffer.putInt(pos, v); else throw new IndexOutOfBoundsException(); } @Override public void writeOrderedInt(int v) { writeInt(v); writeBarrier(); } @Override public void writeOrderedInt(long offset, int v) { writeInt(offset, v); writeBarrier(); } @Override public boolean compareAndSwapInt(long offset, int expected, int x) { if (buffer instanceof DirectBuffer) return NativeBytes.UNSAFE.compareAndSwapInt(null, ((DirectBuffer) buffer).address() + offset, expected, x); return NativeBytes.UNSAFE.compareAndSwapInt(buffer.array(), NativeBytes.BYTES_OFFSET + offset, expected, x); } @Override public void writeLong(long v) { if (position + 8 <= limit) { buffer.putLong(position, v); position += 8; } else { throw new IndexOutOfBoundsException(); } } @Override public void writeLong(long offset, long v) { int pos = (int) (start + offset); if (pos + 8 <= limit) buffer.putLong(pos, v); else throw new IndexOutOfBoundsException(); } @Override public void writeOrderedLong(long v) { writeLong(v); writeBarrier(); } @Override public void writeOrderedLong(long offset, long v) { writeLong((int) offset, v); writeBarrier(); } @Override public boolean compareAndSwapLong(long offset, long expected, long x) { if (buffer instanceof DirectBuffer) return NativeBytes.UNSAFE.compareAndSwapLong(null, ((DirectBuffer) buffer).address() + offset, expected, x); return NativeBytes.UNSAFE.compareAndSwapLong(buffer.array(), NativeBytes.BYTES_OFFSET + offset, expected, x); } @Override public void writeFloat(float v) { if (position + 4 <= limit) { buffer.putFloat(position, v); position += 4; } else { throw new IndexOutOfBoundsException(); } } @Override public void writeFloat(long offset, float v) { int pos = (int) (start + offset); if (pos + 4 <= limit) buffer.putFloat(pos, v); else throw new IndexOutOfBoundsException(); } @Override public void writeDouble(double v) { if (position + 8 <= limit) { buffer.putDouble(position, v); position += 8; } else { throw new IndexOutOfBoundsException(); } } @Override public void writeDouble(long offset, double v) { int pos = (int) (start + offset); if (pos + 8 <= limit) buffer.putDouble(pos, v); else throw new IndexOutOfBoundsException(); } @Override public void readObject(Object object, int start, int end) { throw new UnsupportedOperationException(); } @Override public void writeObject(Object object, int start, int end) { throw new UnsupportedOperationException(); } @Override public long position() { return position - start; } @Override public void position(long position) { if (start + position > Integer.MAX_VALUE) throw new IndexOutOfBoundsException("Position to large"); this.position = (int) (start + position); } @Override public long capacity() { return limit - start; } @Override public long remaining() { return limit - position; } @NotNull @Override public ByteOrder byteOrder() { return buffer.order(); } @Override public void checkEndOfBuffer() throws IndexOutOfBoundsException { if (position < start || position > limit) throw new IndexOutOfBoundsException(); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/ByteStringAppender.java000077500000000000000000000040011226752375100270440ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author peter.lawrey */ public interface ByteStringAppender extends Appendable, BytesCommon { @NotNull ByteStringAppender append(@NotNull CharSequence s); @NotNull ByteStringAppender append(@NotNull CharSequence s, int start, int end); /** * Writes "true" or "false". * * @param b to write. * @return this. */ @NotNull ByteStringAppender append(boolean b); @NotNull ByteStringAppender append(char c); @NotNull ByteStringAppender append(@Nullable Enum value); @NotNull ByteStringAppender append(int i); @NotNull ByteStringAppender append(long l); @NotNull ByteStringAppender append(long l, int base); @NotNull ByteStringAppender appendTimeMillis(long timeInMS); @NotNull ByteStringAppender appendDateMillis(long timeInMS); @NotNull ByteStringAppender appendDateTimeMillis(long timeInMS); // ByteStringAppender append(float f); // ByteStringAppender append(float f, int precision); @NotNull ByteStringAppender append(double d); @NotNull ByteStringAppender append(double d, int precision); @NotNull ByteStringAppender append(@NotNull MutableDecimal md); @NotNull ByteStringAppender append(@NotNull Iterable list, @NotNull CharSequence separator); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/ByteStringParser.java000077500000000000000000000046751226752375100265630ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author peter.lawrey */ public interface ByteStringParser extends BytesCommon { /** * Return true or false, or null if it could not be detected as true or false. Case is not important *

* false: f, false, n, no, 0 *

* true: t, true, y, yes, 1 * * @param tester to detect the end of the text. * @return true, false, or null if neither. */ Boolean parseBoolean(@NotNull StopCharTester tester); /** * Populate a StringBuilder with the UTF encoded text until the end. * * @param builder to clear and append to. * @param tester to detect when to stop. */ void parseUTF(@NotNull StringBuilder builder, @NotNull StopCharTester tester); @NotNull String parseUTF(@NotNull StopCharTester tester); @Nullable > E parseEnum(@NotNull Class eClass, @NotNull StopCharTester tester); @NotNull MutableDecimal parseDecimal(@NotNull MutableDecimal decimal); /** * @return the next long, stopping at the first invalid character */ long parseLong(); /** * @param base to use. * @return the next long, stopping at the first invalid character */ long parseLong(int base); double parseDouble(); /** * Make sure we just read a stop character * * @param tester to stop at * @return true if we stopped at a stop character, false if we ran out of data. */ boolean stepBackAndSkipTo(@NotNull StopCharTester tester); /** * Wind from this positionAddr to the end of the field * * @param tester to stop at * @return true if we stopped at a stop character, false if we ran out of data. */ boolean skipTo(@NotNull StopCharTester tester); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/Bytes.java000077500000000000000000000015721226752375100243730ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.io.serialization.BytesMarshallable; /** * @author peter.lawrey */ public interface Bytes extends RandomDataInput, RandomDataOutput, RandomDataUpdate, ByteStringAppender, ByteStringParser, CharSequence, BytesMarshallable { } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/BytesCommon.java000077500000000000000000000046611226752375100255460ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.io.serialization.BytesMarshallerFactory; import org.jetbrains.annotations.NotNull; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteOrder; /** * @author peter.lawrey */ public interface BytesCommon { /** * @return the offset read/written so far */ long position(); /** * @param position to skip to */ void position(long position); /** * @return space available */ long capacity(); /** * @return space remaining in bytes */ long remaining(); /** * Mark the end of the message if writing and check we are at the end of the message if reading. * * @throws IndexOutOfBoundsException if too much data was written. */ void finish() throws IndexOutOfBoundsException; /** * @return has finish been called. */ boolean isFinished(); /** * Start again, unfinished, position() == 0 */ void reset(); /** * @return Byte order for reading binary */ @NotNull ByteOrder byteOrder(); /** * @return these Bytes as an InputStream */ @NotNull InputStream inputStream(); /** * @return these Bytes as an OutputStream */ @NotNull OutputStream outputStream(); /** * @return the factory for marshallers. */ @NotNull BytesMarshallerFactory bytesMarshallerFactory(); /** * @throws IndexOutOfBoundsException if the bounds of the Bytes has been exceeded. */ void checkEndOfBuffer() throws IndexOutOfBoundsException; /** * Copy from one Bytes to another, moves the position by length * * @param bytes to copy * @param position to copy from * @param length to copy */ void write(BytesCommon bytes, long position, long length); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/DirectBytes.java000077500000000000000000000024611226752375100255240ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; /** * @author peter.lawrey */ public class DirectBytes extends NativeBytes { @NotNull private final DirectStore store; DirectBytes(@NotNull DirectStore store) { super(store.bytesMarshallerFactory, store.address, store.address, store.address + store.size); this.store = store; } public void positionAndSize(long offset, long size) { if (offset < 0 || size < 0 || offset + size > store.size) throw new IllegalArgumentException(); startAddr = positionAddr = store.address + offset; limitAddr = startAddr + size; } public DirectStore store() { return store; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/DirectStore.java000077500000000000000000000054531226752375100255360ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.io.serialization.BytesMarshallerFactory; import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory; import org.jetbrains.annotations.NotNull; import sun.misc.Cleaner; /** * @author peter.lawrey */ public class DirectStore { protected BytesMarshallerFactory bytesMarshallerFactory; private final Cleaner cleaner; protected long address; protected long size; public DirectStore(long size) { this(new VanillaBytesMarshallerFactory(), size); } public DirectStore(BytesMarshallerFactory bytesMarshallerFactory, long size) { this(bytesMarshallerFactory, size, true); } public DirectStore(BytesMarshallerFactory bytesMarshallerFactory, long size, boolean zeroOut) { this.bytesMarshallerFactory = bytesMarshallerFactory; address = NativeBytes.UNSAFE.allocateMemory(size); // System.out.println("old value " + Integer.toHexString(NativeBytes.UNSAFE.getInt(null, address))); if (zeroOut) { NativeBytes.UNSAFE.setMemory(address, size, (byte) 0); NativeBytes.UNSAFE.putLongVolatile(null, address, 0L); } this.size = size; cleaner = Cleaner.create(this, new Runnable() { @Override public void run() { if (address != 0) NativeBytes.UNSAFE.freeMemory(address); address = DirectStore.this.size = 0; } }); } @NotNull public static DirectStore allocate(long size) { return new DirectStore(null, size); } @NotNull public static DirectStore allocateLazy(long size) { return new DirectStore(null, size, false); } /* public void resize(long newSize) { if (newSize == size) return; address = NativeBytes.UNSAFE.reallocateMemory(address, newSize); size = newSize; }*/ @NotNull public DirectBytes createSlice() { return new DirectBytes(this); } public void free() { cleaner.clean(); } public long size() { return size; } public BytesMarshallerFactory bytesMarshallerFactory() { return bytesMarshallerFactory; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/IOTools.java000077500000000000000000000043631226752375100246360ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.logging.Logger; /** * @author peter.lawrey */ public enum IOTools { ; public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); public static final Charset UTF_8 = Charset.forName("UTF-8"); public static void close(@Nullable Closeable closeable) { if (closeable == null) return; try { closeable.close(); } catch (IOException ignored) { } } public static void close(@NotNull Iterable closeables) { for (Closeable closeable : closeables) { close(closeable); } } public static int stopBitLength(long l) { if (l < 0) return stopBitLength(~l) + 1; int count = 1; while (l >= 128) { l >>>= 7; count++; } return count; } public static void deleteDir(String dirPath) { deleteDir(new File(dirPath)); } public static void deleteDir(File dir) { // delete one level. if (dir.isDirectory()) { File[] files = dir.listFiles(); if (files != null) for (File file : files) if (file.isDirectory()) { deleteDir(file); } else if (!file.delete()) { Logger.getLogger(IOTools.class.getName()).info("... unable to delete " + file); } } dir.delete(); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/MappedFile.java000066400000000000000000000116671226752375100253160ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; /** * This manages the full life cycle of a file and its mappings. */ public class MappedFile { private final FileChannel fileChannel; private final String basePath; private final long blockSize; private final long overlapSize; private final List maps = new ArrayList(); // short list of the last two mappings. private volatile MappedMemory map0, map1; public MappedFile(String basePath, long blockSize) throws FileNotFoundException { this(basePath, blockSize, 0L); } public MappedFile(String basePath, long blockSize, long overlapSize) throws FileNotFoundException { this.basePath = basePath; this.blockSize = blockSize; this.overlapSize = overlapSize; fileChannel = new RandomAccessFile(basePath, "rw").getChannel(); } public static MappedByteBuffer getMap(@NotNull FileChannel fileChannel, long start, int size) throws IOException { for (int i = 1; ; i++) { try { // long startTime = System.nanoTime(); @SuppressWarnings("UnnecessaryLocalVariable") MappedByteBuffer map = fileChannel.map(FileChannel.MapMode.READ_WRITE, start, size); map.order(ByteOrder.nativeOrder()); // long time = System.nanoTime() - startTime; // System.out.printf("Took %,d us to map %,d MB%n", time / 1000, size / 1024 / 1024); // System.out.println("Map size: "+size); return map; } catch (IOException e) { if (e.getMessage() == null || !e.getMessage().endsWith("user-mapped section open")) { throw e; } if (i < 10) //noinspection CallToThreadYield Thread.yield(); else try { //noinspection BusyWait Thread.sleep(1); } catch (InterruptedException ignored) { Thread.currentThread().interrupt(); throw e; } } } } public MappedMemory acquire(long index) throws IOException { return acquire(index, false); } public MappedMemory acquire(long index, boolean prefetch) throws IOException { MappedMemory map0 = this.map0, map1 = this.map1; if (map0 != null && map0.index() == index) { map0.reserve(); return map0; } if (map1 != null && map1.index() == index) { map1.reserve(); return map1; } return acquire0(index, prefetch); } private synchronized MappedMemory acquire0(long index, boolean prefetch) throws IOException { if (map1 != null) map1.release(); map1 = map0; map0 = new MappedMemory(fileChannel.map(FileChannel.MapMode.READ_WRITE, index * blockSize, blockSize + overlapSize), index); map0.reserve(); maps.add(map0); // clean up duds. for (int i = maps.size() - 1; i >= 0; i--) { if (maps.get(i).refCount() <= 0) maps.remove(i); } return map0; } public synchronized void close() throws IOException { if (map1 != null) { map1.release(); map1 = null; } if (map0 != null) { map0.release(); map0 = null; } // clean up errant maps. int count = 0; for (int i = maps.size() - 1; i >= 0; i--) { if (maps.get(i).refCount() <= 0) { maps.get(i).close(); count++; } } if (count > 1) Logger.getLogger(MappedFile.class.getName()).info(basePath + " memory mappings left unreleased, num= " + count); maps.clear(); fileChannel.close(); } public long size() { try { return fileChannel.size(); } catch (IOException e) { return 0; } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/MappedMemory.java000066400000000000000000000041151226752375100256750ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import sun.misc.Cleaner; import sun.nio.ch.DirectBuffer; import java.nio.MappedByteBuffer; import java.util.concurrent.atomic.AtomicInteger; public class MappedMemory { private final MappedByteBuffer buffer; private final long index; private final AtomicInteger refCount = new AtomicInteger(1); private volatile boolean unmapped = false; public MappedMemory(MappedByteBuffer buffer, long index) { this.buffer = buffer; this.index = index; } private static void unmap(MappedByteBuffer bb) { Cleaner cl = ((DirectBuffer) bb).cleaner(); if (cl != null) cl.clean(); } public long index() { return index; } public void reserve() { if (unmapped) throw new IllegalStateException(); refCount.incrementAndGet(); } public void release() { if (unmapped) throw new IllegalStateException(); if (refCount.decrementAndGet() > 0) return; close(); } public MappedByteBuffer buffer() { return buffer; } public long address() { return ((DirectBuffer) buffer).address(); } public int refCount() { return refCount.get(); } public static void release(MappedMemory mapmem) { if (mapmem != null) mapmem.release(); } public void force() { if (!unmapped) buffer.force(); } public void close() { unmap(buffer); unmapped = true; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/MultiStoreBytes.java000066400000000000000000000024041226752375100264130ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; public class MultiStoreBytes extends NativeBytes { private DirectStore store; public MultiStoreBytes() { super(NO_PAGE, NO_PAGE, NO_PAGE); this.store = store; } public void storePositionAndSize(DirectStore store, long offset, long size) { if (offset < 0 || size < 0 || offset + size > store.size) throw new IllegalArgumentException(); this.store = store; this.bytesMarshallerFactory = store.bytesMarshallerFactory; startAddr = positionAddr = store.address + offset; limitAddr = startAddr + size; } public DirectStore store() { return store; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/MutableDecimal.java000077500000000000000000000125031226752375100261510ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import java.math.BigDecimal; import java.math.RoundingMode; /** * @author peter.lawrey */ @SuppressWarnings({"CompareToUsesNonFinalVariable", "NonFinalFieldReferenceInEquals", "NonFinalFieldReferencedInHashCode"}) public class MutableDecimal extends Number implements Comparable { static final double[] TENS = new double[16]; static { TENS[0] = 1; for (int i = 1; i < TENS.length; i++) TENS[i] = 10 * TENS[i - 1]; } private long value; private int scale; public MutableDecimal() { this(0, Integer.MIN_VALUE); } public MutableDecimal(long value, int scale) { this.value = value; this.scale = scale; } public MutableDecimal(long value) { this(value, 0); } public MutableDecimal(double d, int precision) { set(d, precision); } public void set(double d, int precision) { double d2 = precision > 0 ? d * tens(precision) : d / tens(-precision); scale = precision; if (Math.abs(d2) < 1e16) { value = Math.round(d2); } else { BigDecimal bd = BigDecimal.valueOf(d).setScale(precision, RoundingMode.HALF_UP); value = bd.unscaledValue().longValue(); } } public void set(long value, int scale) { this.value = value; this.scale = scale; } public long value() { return value; } public int scale() { return scale; } public void clear() { scale = Integer.MIN_VALUE; } public boolean isSet() { return scale > Integer.MIN_VALUE; } @Override public int hashCode() { int hash = (int) value; hash ^= value >>> 32; hash ^= scale * 37; return hash; } @Override public boolean equals(Object obj) { if (!(obj instanceof MutableDecimal)) return false; MutableDecimal md = (MutableDecimal) obj; return value == md.value && scale == md.scale; } @NotNull @Override public String toString() { StringBuilder sb = new StringBuilder(20); toString(sb); return sb.toString(); } public void toString(@NotNull StringBuilder sb) { if (scale == Integer.MIN_VALUE) { sb.append("not set"); return; } if (value == 0 && scale <= 0) { sb.append('0'); return; } boolean neg = false; long v = value; int s = scale; if (v < 0) { v = -value; neg = true; } for (int s2 = scale; s2 < 0; s2++) sb.append('0'); while (v != 0 || s >= 0) { int digit = (int) (v % 10); // MIN_VALUE if (digit < 0) { digit = 8; v = (v >>> 1) / 5; } else { v /= 10; } sb.append((char) ('0' + digit)); if (--s == 0) sb.append('.'); } if (neg) sb.append('-'); sb.reverse(); } @NotNull @Override public MutableDecimal clone() throws CloneNotSupportedException { return (MutableDecimal) super.clone(); } @Override public int intValue() { return (int) longValue(); } @Override public long longValue() { if (scale == 0) return value; if (scale > 0 && scale < TENS.length) return value / (long) TENS[scale]; if (scale < 0 && -scale < TENS.length) return value * (long) TENS[-scale]; return (long) doubleValue(); } @Override public float floatValue() { return (float) doubleValue(); } public double doubleValue() { if (scale == 0) return value; return scale <= 0 ? value * tens(-scale) : value / tens(scale); } private static double tens(int scale) { return scale < TENS.length ? TENS[scale] : Math.pow(10, scale); } @Override public int compareTo(@NotNull MutableDecimal o) { long value = this.value, ovalue = o.value; if (scale == o.scale) return longCompareTo(value, ovalue); if (value == 0 && ovalue == 0) return 0; double d = doubleValue(), od = o.doubleValue(); double err = (Math.abs(d) + Math.abs(od)) / 1e15; if (d + err < od) return -1; if (d > od + err) return +1; // fallback. return BigDecimal.valueOf(value, scale).compareTo(BigDecimal.valueOf(ovalue, o.scale())); } private static int longCompareTo(long value, long ovalue) { return value < ovalue ? -1 : value > ovalue ? +1 : 0; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/NativeBytes.java000077500000000000000000000254711226752375100255460ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.io.serialization.BytesMarshallerFactory; import org.jetbrains.annotations.NotNull; import sun.misc.Unsafe; import java.io.EOFException; import java.lang.reflect.Field; import java.nio.ByteOrder; /** * @author peter.lawrey */ public class NativeBytes extends AbstractBytes { /** * *** Access the Unsafe class ***** */ @NotNull @SuppressWarnings("ALL") public static final Unsafe UNSAFE; static final int BYTES_OFFSET; static { try { @SuppressWarnings("ALL") Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); UNSAFE = (Unsafe) theUnsafe.get(null); BYTES_OFFSET = UNSAFE.arrayBaseOffset(byte[].class); } catch (Exception e) { throw new AssertionError(e); } } protected static final long NO_PAGE = UNSAFE.allocateMemory(UNSAFE.pageSize()); protected long startAddr; protected long positionAddr; protected long limitAddr; public NativeBytes(long startAddr, long positionAddr, long limitAddr) { this.startAddr = startAddr; this.positionAddr = positionAddr; this.limitAddr = limitAddr; } public NativeBytes(BytesMarshallerFactory bytesMarshallerFactory, long startAddr, long positionAddr, long limitAddr) { super(bytesMarshallerFactory); this.startAddr = startAddr; this.positionAddr = positionAddr; this.limitAddr = limitAddr; } public NativeBytes(NativeBytes bytes) { super(bytes.bytesMarshallerFactory()); this.startAddr = bytes.startAddr; this.positionAddr = bytes.positionAddr; this.limitAddr = bytes.limitAddr; } public static long longHash(byte[] bytes, int off, int len) { long hash = 0; int pos = 0; for (; pos < len - 7; pos += 8) hash = hash * 10191 + UNSAFE.getLong(bytes, (long) BYTES_OFFSET + off + pos); for (; pos < len; pos++) hash = hash * 57 + bytes[off + pos]; return hash; } @Override public int read(@NotNull byte[] bytes, int off, int len) { if (len < 0 || off < 0 || off + len > bytes.length) throw new IllegalArgumentException(); long left = remaining(); if (left <= 0) return -1; int len2 = (int) Math.min(len, left); UNSAFE.copyMemory(null, positionAddr, bytes, BYTES_OFFSET + off, len2); positionAddr += len2; return len2; } @Override public byte readByte() { return UNSAFE.getByte(positionAddr++); } @Override public byte readByte(long offset) { return UNSAFE.getByte(startAddr + offset); } @Override public void readFully(@NotNull byte[] b, int off, int len) { if (len < 0 || off < 0 || off + len > b.length) throw new IllegalArgumentException(); long left = remaining(); if (left < len) throw new IllegalStateException(new EOFException()); UNSAFE.copyMemory(null, positionAddr, b, BYTES_OFFSET + off, len); positionAddr += len; } @Override public short readShort() { short s = UNSAFE.getShort(positionAddr); positionAddr += 2; return s; } @Override public short readShort(long offset) { return UNSAFE.getShort(startAddr + offset); } @Override public char readChar() { char ch = UNSAFE.getChar(positionAddr); positionAddr += 2; return ch; } @Override public char readChar(long offset) { return UNSAFE.getChar(startAddr + offset); } @Override public int readInt() { int i = UNSAFE.getInt(positionAddr); positionAddr += 4; return i; } @Override public int readInt(long offset) { return UNSAFE.getInt(startAddr + offset); } @Override public int readVolatileInt() { int i = UNSAFE.getIntVolatile(null, positionAddr); positionAddr += 4; return i; } @Override public int readVolatileInt(long offset) { return UNSAFE.getIntVolatile(null, startAddr + offset); } @Override public long readLong() { long l = UNSAFE.getLong(positionAddr); positionAddr += 8; return l; } @Override public long readLong(long offset) { return UNSAFE.getLong(startAddr + offset); } @Override public long readVolatileLong() { long l = UNSAFE.getLongVolatile(null, positionAddr); positionAddr += 8; return l; } @Override public long readVolatileLong(long offset) { return UNSAFE.getLongVolatile(null, startAddr + offset); } @Override public float readFloat() { float f = UNSAFE.getFloat(positionAddr); positionAddr += 4; return f; } @Override public float readFloat(long offset) { return UNSAFE.getFloat(startAddr + offset); } @Override public double readDouble() { double d = UNSAFE.getDouble(positionAddr); positionAddr += 8; return d; } @Override public double readDouble(long offset) { return UNSAFE.getDouble(startAddr + offset); } @Override public void write(int b) { UNSAFE.putByte(positionAddr++, (byte) b); } @Override public void writeByte(long offset, int b) { UNSAFE.putByte(startAddr + offset, (byte) b); } @Override public void write(long offset, @NotNull byte[] bytes) { if (offset < 0 || offset + bytes.length > capacity()) throw new IllegalArgumentException(); UNSAFE.copyMemory(bytes, BYTES_OFFSET, null, startAddr + offset, bytes.length); positionAddr += bytes.length; } @Override public void write(byte[] bytes, int off, int len) { UNSAFE.copyMemory(bytes, BYTES_OFFSET + off, null, positionAddr, len); positionAddr += len; } @Override public void writeShort(int v) { UNSAFE.putShort(positionAddr, (short) v); positionAddr += 2; } @Override public void writeShort(long offset, int v) { UNSAFE.putShort(startAddr + offset, (short) v); } @Override public void writeChar(int v) { UNSAFE.putChar(positionAddr, (char) v); positionAddr += 2; } @Override public void writeChar(long offset, int v) { UNSAFE.putChar(startAddr + offset, (char) v); } @Override public void writeInt(int v) { UNSAFE.putInt(null, positionAddr, v); positionAddr += 4; } @Override public void writeInt(long offset, int v) { UNSAFE.putInt(startAddr + offset, v); } @Override public void writeOrderedInt(int v) { UNSAFE.putOrderedInt(null, positionAddr, v); positionAddr += 4; } @Override public void writeOrderedInt(long offset, int v) { UNSAFE.putOrderedInt(null, startAddr + offset, v); } @Override public boolean compareAndSwapInt(long offset, int expected, int x) { return UNSAFE.compareAndSwapInt(null, startAddr + offset, expected, x); } @Override public void writeLong(long v) { UNSAFE.putLong(positionAddr, v); positionAddr += 8; } @Override public void writeLong(long offset, long v) { UNSAFE.putLong(startAddr + offset, v); } @Override public void writeOrderedLong(long v) { UNSAFE.putOrderedLong(null, positionAddr, v); positionAddr += 8; } @Override public void writeOrderedLong(long offset, long v) { UNSAFE.putOrderedLong(null, startAddr + offset, v); } @Override public boolean compareAndSwapLong(long offset, long expected, long x) { return UNSAFE.compareAndSwapLong(null, startAddr + offset, expected, x); } @Override public void writeFloat(float v) { UNSAFE.putFloat(positionAddr, v); positionAddr += 4; } @Override public void writeFloat(long offset, float v) { UNSAFE.putFloat(startAddr + offset, v); } @Override public void writeDouble(double v) { UNSAFE.putDouble(positionAddr, v); positionAddr += 8; } @Override public void writeDouble(long offset, double v) { UNSAFE.putDouble(startAddr + offset, v); } @Override public void readObject(Object object, int start, int end) { int len = end - start; for (; len >= 8; len -= 8) { UNSAFE.putLong(object, (long) start, UNSAFE.getLong(positionAddr)); positionAddr += 8; start += 8; } for (; len > 0; len--) { UNSAFE.putByte(object, (long) start, UNSAFE.getByte(positionAddr)); positionAddr++; start++; } } @Override public void writeObject(Object object, int start, int end) { int len = end - start; for (; len >= 8; len -= 8) { UNSAFE.putLong(positionAddr, UNSAFE.getLong(object, (long) start)); positionAddr += 8; start += 8; } for (; len > 0; len--) { UNSAFE.putByte(positionAddr, UNSAFE.getByte(object, (long) start)); positionAddr++; start++; } } @Override public long position() { return (positionAddr - startAddr); } @Override public void position(long position) { this.positionAddr = startAddr + position; } @Override public long capacity() { return (limitAddr - startAddr); } @Override public long remaining() { return (limitAddr - positionAddr); } @NotNull @Override public ByteOrder byteOrder() { return ByteOrder.nativeOrder(); } @Override public void checkEndOfBuffer() throws IndexOutOfBoundsException { if (position() > capacity()) throw new IndexOutOfBoundsException("position is beyond the end of the buffer " + position() + " > " + capacity()); } public long startAddr() { return startAddr; } public long positionAddr() { return positionAddr; } public void positionAddr(long positionAddr) { this.positionAddr = positionAddr; } public long limitAddr() { return limitAddr; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/RandomDataInput.java000077500000000000000000001145031226752375100263360ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.ObjectInput; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Map; import java.util.RandomAccess; /** * @author peter.lawrey */ public interface RandomDataInput extends ObjectInput, RandomAccess, BytesCommon { /** * Reads some bytes from an input stream and stores them into the buffer array b. The number of bytes * read is equal to the length of b. *

* This method blocks until one of the following conditions occurs:

  • b.length bytes of input * data are available, in which case a normal return is made. *

    *

  • End of file is detected, in which case an EOFException is thrown. *

    *

  • An I/O error occurs, in which case an IOException other than EOFException is * thrown.
*

* If b is null, a NullPointerException is thrown. If b.length * is zero, then no bytes are read. Otherwise, the first byte read is stored into element b[0], the * next one into b[1], and so on. If an exception is thrown from this method, then it may be that some * but not all bytes of b have been updated with data from the input stream. * * @param bytes the buffer into which the data is read. */ @Override void readFully(@NotNull byte[] bytes); /** * Reads len bytes from an input stream. *

* This method blocks until one of the following conditions occurs:

  • len bytes of input data * are available, in which case a normal return is made. *

    *

  • End of file is detected, in which case an EOFException is thrown. *

    *

  • An I/O error occurs, in which case an IOException other than EOFException is * thrown.
*

* If b is null, a NullPointerException is thrown. If off is * negative, or len is negative, or off+len is greater than the length of the array * b, then an IndexOutOfBoundsException is thrown. If len is zero, then no * bytes are read. Otherwise, the first byte read is stored into element b[off], the next one into * b[off+1], and so on. The number of bytes read is, at most, equal to len. * * @param bytes the buffer into which the data is read. * @param off an int specifying the offset into the data. * @param len an int specifying the number of bytes to read. */ @Override void readFully(@NotNull byte[] bytes, int off, int len); /** * Makes an attempt to skip over n bytes of data from the input stream, discarding the skipped bytes. * However, it may skip over some smaller number of bytes, possibly zero. This may result from any of a number of * conditions; reaching end of file before n bytes have been skipped is only one possibility. This * method never throws an EOFException. The actual number of bytes skipped is returned. * * @param n the number of bytes to be skipped. * @return the number of bytes actually skipped. */ @Override int skipBytes(int n); /** * Reads one input byte and returns true if that byte is nonzero, false if that byte is * zero. This method is suitable for reading the byte written by the writeBoolean method of interface * DataOutput. * * @return the boolean value read. */ @Override boolean readBoolean(); /** * Reads one input byte and returns true if that byte is nonzero, false if that byte is * zero. This method is suitable for reading the byte written by the writeBoolean method of interface * RandomDataOutput. * * @param offset to read byte translated into a boolean * @return the boolean value read. */ boolean readBoolean(long offset); /** * Reads and returns one input byte. The byte is treated as a signed value in the range -128 through * 127, inclusive. This method is suitable for reading the byte written by the writeByte * method of interface DataOutput. * * @return the 8-bit value read. */ @Override byte readByte(); /** * Reads and returns one input byte. The byte is treated as a signed value in the range -128 through * 127, inclusive. This method is suitable for reading the byte written by the writeByte * method of interface RandomDataOutput. * * @param offset of byte to read. * @return the 8-bit value read. */ byte readByte(long offset); /** * Reads one input byte, zero-extends it to type int, and returns the result, which is therefore in the * range 0 through 255. This method is suitable for reading the byte written by the * writeByte method of interface DataOutput if the argument to writeByte was * intended to be a value in the range 0 through 255. * * @return the unsigned 8-bit value read. */ @Override int readUnsignedByte(); /** * Reads one input byte, zero-extends it to type int, and returns the result, which is therefore in the * range 0 through 255. This method is suitable for reading the byte written by the * writeByte method of interface RandomDataOutput if the argument to * writeByte was intended to be a value in the range 0 through 255. * * @param offset of byte to read * @return the unsigned 8-bit value read. */ int readUnsignedByte(long offset); /** * Reads two input bytes and returns a short value. Let a be the first byte read and * b be the second byte on big endian machines, and the opposite on little endian machines. The value * returned is: *

(short)((a << 8) | (b & 0xff))
     * 
* This method is suitable for reading the bytes written by the writeShort method of interface * DataOutput. * * @return the 16-bit value read. */ @Override short readShort(); /** * Reads two input bytes and returns a short value. Let a be the first byte read and * b be the second byte on big endian machines, and the opposite on little endian machines. The value * returned is: *


     *     (short)((a << 8) | (b & 0xff))
     * 
* This method is suitable for reading the bytes written by the writeShort method of interface * RandomDataOutput. * * @param offset of short to read. * @return the 16-bit value read. */ short readShort(long offset); /** * Reads two input bytes and returns an int value in the range 0 through * 65535. Let a be the first byte read and b be the second byte on big endian * machines, and the opposite on little endian machines. The value returned is: *


     *     (((a & 0xff) << 8) | (b & 0xff))
     * 
* This method is suitable for reading the bytes written by the writeUnsignedShort method of interface * DataOutput if the argument to writeUnsignedShort was intended to be a value in the * range 0 through 65535. * * @return the unsigned 16-bit value read. */ @Override int readUnsignedShort(); /** * Reads two input bytes and returns an int value in the range 0 through * 65535. Let a be the first byte read and b be the second byte on big endian * machines, and the opposite on little endian machines. The value returned is: *


     *     (((a & 0xff) << 8) | (b & 0xff))
     * 
* This method is suitable for reading the bytes written by the writeShort method of interface * RandomDataOutput if the argument to writeUnsignedShort was intended to be a value in * the range 0 through 65535. * * @param offset of short to read. * @return the unsigned 16-bit value read. */ int readUnsignedShort(long offset); /** * Reads one or three input bytes and returns a short value. Let a be the first byte read. * This mapped as follows; Byte.MIN_VALUE => Short.MIN_VALUE, Byte.MAX_VALUE => Short.MAX_VALUE, Byte.MIN_VALUE+2 to * Byte.MAX_VALUE-1 => same as short value, Byte.MIN_VALUE+1 => readShort(). *

* This method is suitable for reading the bytes written by the writeCompactShort method of interface * RandomDataOutput. * * @return the 16-bit value read. */ short readCompactShort(); /** * Reads one or three input bytes and returns a short value. Let a be the first byte read. * This mapped as follows; -1 => readUnsignedShort(), default => (a & 0xFF) *

* This method is suitable for reading the bytes written by the writeCompactUnsignedShort method of * interface RandomDataOutput. * * @return the unsigned 16-bit value read. */ int readCompactUnsignedShort(); /** * Reads two input bytes and returns a char value. Let a be the first byte read and * b be the second byte on big endian machines, and the opposite on little endian machines. The value * returned is: *

(char)((a << 8) | (b & 0xff))
     * 
* This method is suitable for reading bytes written by the writeChar method of interface * DataOutput. * * @return the char value read. */ @Override char readChar(); /** * Reads two input bytes and returns a char value. Let a be the first byte read and * b be the second byte on big endian machines, and the opposite on little endian machines. The value * returned is: *

(char)((a << 8) | (b & 0xff))
     * 
* This method is suitable for reading bytes written by the writeChar method of interface * RandomDataOutput. * * @param offset of the char to read. * @return the char value read. */ char readChar(long offset); /** * Reads three input bytes and returns a 24-bit int value. Let a-c be the first through * third bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

     * 
     * ((((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8))) >> 8
     * 
* This method is suitable for reading bytes written by the writeInt24 method of interface * RandomDataOutput. * * @return the int value read. */ int readInt24(); /** * Reads three input bytes and returns a 24-bit int value. Let a-c be the first through * third bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

     * 
     * ((((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8))) >> 8
     * 
* This method is suitable for reading bytes written by the writeInt24 method of interface * RandomDataOutput. * * @param offset to read from * @return the int value read. */ int readInt24(long offset); /** * Reads four input bytes and returns an int value. Let a-d be the first through fourth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

     * 
     * (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff))
     * 
* This method is suitable for reading bytes written by the writeInt method of interface * DataOutput. * * @return the int value read. */ @Override int readInt(); /** * Reads four input bytes and returns an int value. Let a-d be the first through fourth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

     * 
     * (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff))
     * 
* This method is suitable for reading bytes written by the writeInt method of interface * RandomDataOutput. * * @param offset to read from * @return the int value read. */ int readInt(long offset); /** * This is the same as readInt() except a read barrier is performed first.

Reads four input bytes and returns * an int value. Let a-d be the first through fourth bytes read on big endian machines, * and the opposite on little endian machines. The value returned is: *

     * 
     * (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff))
     * 
* This method is suitable for reading bytes written by the writeOrderedInt or * writeVolatileInt method of interface RandomDataOutput. * * @return the int value read. */ int readVolatileInt(); /** * This is the same as readInt() except a read barrier is performed first.

Reads four input bytes and returns * an int value. Let a-d be the first through fourth bytes read on big endian machines, * and the opposite on little endian machines. The value returned is: *

     * 
     * (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff))
     * 
* This method is suitable for reading bytes written by the writeOrderedInt or * writeVolatileInt method of interface RandomDataOutput. * * @param offset to read from * @return the int value read. */ int readVolatileInt(long offset); /** * Reads four input bytes and returns an int value. Let a-d be the first through fourth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

     * 
     * ((((long) a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d &
     * 0xff))
     * 
* This method is suitable for reading bytes written by the writeUnsignedInt method of interface * RandomDataOutput. * * @return the unsigned int value read. */ long readUnsignedInt(); /** * Reads four input bytes and returns an int value. Let a-d be the first through fourth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

     * 
     * ((((long) a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d &
     * 0xff))
     * 
* This method is suitable for reading bytes written by the writeUnsignedInt method of interface * RandomDataOutput. * * @param offset to read from * @return the unsigned int value read. */ long readUnsignedInt(long offset); /** * Reads two or six input bytes and returns an int value. Let a be the first short read * with readShort(). This mapped as follows; Short.MIN_VALUE => Integer.MIN_VALUE, Short.MAX_VALUE => * Integer.MAX_VALUE, Short.MIN_VALUE+2 to Short.MAX_VALUE-1 => same as short value, Short.MIN_VALUE+1 => * readInt(). *

* This method is suitable for reading the bytes written by the writeCompactInt method of interface * RandomDataOutput. * * @return the 32-bit value read. */ int readCompactInt(); /** * Reads two or six input bytes and returns an int value. Let a be the first short read * with readShort(). This mapped as follows; -1 => readUnsignedInt(), default => (a & 0xFFFF) *

* This method is suitable for reading the bytes written by the writeCompactUnsignedInt method of * interface RandomDataOutput. * * @return the unsigned 32-bit value read. */ long readCompactUnsignedInt(); /** * Reads eight input bytes and returns a long value. Let a-h be the first through eighth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

 
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16) |
     *  ((long)(g & 0xff) <<  8) |
     *  ((long)(h & 0xff)))
     * 
*

* This method is suitable for reading bytes written by the writeLong method of interface * DataOutput. * * @return the long value read. */ @Override long readLong(); /** * Reads eight input bytes and returns a long value. Let a-h be the first through eighth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

 
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16) |
     *  ((long)(g & 0xff) <<  8) |
     *  ((long)(h & 0xff)))
     * 
*

* This method is suitable for reading bytes written by the writeLong method of interface * RandomDataOutput. * * @param offset of the long to read * @return the long value read. */ long readLong(long offset); /** * This is the same readLong() except a dread barrier is performed first *

* Reads eight input bytes and returns a long value. Let a-h be the first through eighth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

 
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16) |
     *  ((long)(g & 0xff) <<  8) |
     *  ((long)(h & 0xff)))
     * 
*

* This method is suitable for reading bytes written by the writeOrderedLong or * writeVolatileLong method of interface RandomDataOutput. * * @return the long value read. */ long readVolatileLong(); /** * This is the same readLong() except a dread barrier is performed first *

* Reads eight input bytes and returns a long value. Let a-h be the first through eighth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

 
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16) |
     *  ((long)(g & 0xff) <<  8) |
     *  ((long)(h & 0xff)))
     * 
*

* This method is suitable for reading bytes written by the writeOrderedLong or * writeVolatileLong method of interface RandomDataOutput. * * @param offset of the long to read * @return the long value read. */ long readVolatileLong(long offset); /** * Reads six input bytes and returns a long value. Let a-f be the first through sixth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

 
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16)) >> 16
     * 
*

* This method is suitable for reading bytes written by the writeInt48 method of interface * RandomDataOutput. * * @return the long value read. */ long readInt48(); /** * Reads six input bytes and returns a long value. Let a-f be the first through sixth * bytes read on big endian machines, and the opposite on little endian machines. The value returned is: *

 
     * (((long)(a & 0xff) << 56) |
     *  ((long)(b & 0xff) << 48) |
     *  ((long)(c & 0xff) << 40) |
     *  ((long)(d & 0xff) << 32) |
     *  ((long)(e & 0xff) << 24) |
     *  ((long)(f & 0xff) << 16)) >> 16
     * 
*

* This method is suitable for reading bytes written by the writeInt48 method of interface * RandomDataOutput. * * @param offset of the long to read * @return the long value read. */ long readInt48(long offset); /** * Reads four or twelve input bytes and returns a long value. Let a be the first int read * with readInt(). This mapped as follows; Integer.MIN_VALUE => Long.MIN_VALUE, Integer.MAX_VALUE => Long.MAX_VALUE, * Integer.MIN_VALUE+2 to Integer.MAX_VALUE-1 => same as short value, Integer.MIN_VALUE+1 => readLong(). *

* This method is suitable for reading the bytes written by the writeCompactLong method of interface * RandomDataOutput. * * @return the 64-bit value read. */ long readCompactLong(); /** * Reads between one and ten bytes with are stop encoded with support for negative numbers *


     * long l = 0, b;
     * int count = 0;
     * while ((b = readByte()) < 0) {
     *     l |= (b & 0x7FL) << count;
     *     count += 7;
     * }
     * if (b == 0 && count > 0)
     *     return ~l;
     * return l | (b << count);
     * 
* * @return a stop bit encoded number as a long. */ long readStopBit(); /** * Reads four input bytes and returns a float value. It does this by first constructing an * int value in exactly the manner of the readInt method, then converting this * int value to a float in exactly the manner of the method * Float.intBitsToFloat. This method is suitable for reading bytes written by the * writeFloat method of interface DataOutput. * * @return the float value read. */ @Override float readFloat(); /** * Reads four input bytes and returns a float value. It does this by first constructing an * int value in exactly the manner of the readInt method, then converting this * int value to a float in exactly the manner of the method * Float.intBitsToFloat. This method is suitable for reading bytes written by the * writeFloat method of interface DataOutput. * * @param offset to read from * @return the float value read. */ float readFloat(long offset); /** * This is the same as readFloat() except a read barrier is performed first.

Reads four input bytes and returns * a float value. *

* This method is suitable for reading bytes written by the writeOrderedFloat method of interface RandomDataOutput. * * @param offset to read from * @return the int value read. */ float readVolatileFloat(long offset); /** * Reads eight input bytes and returns a double value. It does this by first constructing a * long value in exactly the manner of the readLong method, then converting this * long value to a double in exactly the manner of the method * Double.longBitsToDouble. This method is suitable for reading bytes written by the * writeDouble method of interface DataOutput. * * @return the double value read. */ @Override double readDouble(); /** * Reads eight input bytes and returns a double value. It does this by first constructing a * long value in exactly the manner of the readLong method, then converting this * long value to a double in exactly the manner of the method * Double.longBitsToDouble. This method is suitable for reading bytes written by the * writeDouble method of interface DataOutput. * * @param offset to read from * @return the double value read. */ double readDouble(long offset); /** * Reads the first four bytes as readFloat(). If this is Float.NaN, the next eight bytes are read as readDouble() * * @return the double value read. */ double readCompactDouble(); /** * This is the same as readDouble() except a read barrier is performed first.

Reads four input bytes and returns * a float value. *

* This method is suitable for reading bytes written by the writeOrderedFloat method of interface RandomDataOutput. * * @param offset to read from * @return the int value read. */ double readVolatileDouble(long offset); /** * Reads the next line of text from the input stream. It reads successive bytes, converting each byte separately * into a character, until it encounters a line terminator or end of file; the characters read are then returned as * a String. Note that because this method processes bytes, it does not support input of the full * Unicode character set. *

* If end of file is encountered before even one byte can be read, then null is returned. Otherwise, * each byte that is read is converted to type char by zero-extension. If the character * '\n' is encountered, it is discarded and reading ceases. If the character '\r' is * encountered, it is discarded and, if the following byte converts to the character '\n', then * that is discarded also; reading then ceases. If end of file is encountered before either of the characters * '\n' and '\r' is encountered, reading ceases. Once reading has ceased, a * String is returned that contains all the characters read and not discarded, taken in order. Note * that every character in this string will have a value less than \u0100, that is, * (char)256. * * @return the next line of text from the input stream, or null if the end of file is encountered * before a byte can be read. */ @Override @Nullable String readLine(); /** * Reads in a string that has been encoded using a modified UTF-8 format. The general * contract of readUTF is that it reads a representation of a Unicode character string encoded in * modified UTF-8 format; this string of characters is then returned as a String. *

* First, two bytes are read and used to construct an unsigned 16-bit integer in exactly the manner of the * readUnsignedShort method . This integer value is called the UTF length and specifies the * number of additional bytes to be read. These bytes are then converted to characters by considering them in * groups. The length of each group is computed from the value of the first byte of the group. The byte following a * group, if any, is the first byte of the next group. *

* If the first byte of a group matches the bit pattern 0xxxxxxx (where x means "may be * 0 or 1"), then the group consists of just that byte. The byte is zero-extended to form * a character. *

* If the first byte of a group matches the bit pattern 110xxxxx, then the group consists of that byte * a and a second byte b. If there is no byte b (because byte a * was the last of the bytes to be read), or if byte b does not match the bit pattern * 10xxxxxx, then a UTFDataFormatException is thrown. Otherwise, the group is converted to * the character:

*

(char)(((a& 0x1F) << 6) | (b & 0x3F))
     * 
* If the first byte of a group matches the bit pattern 1110xxxx, then the group consists of that byte * a and two more bytes b and c. If there is no byte c (because * byte a was one of the last two of the bytes to be read), or either byte b or byte * c does not match the bit pattern 10xxxxxx, then a UTFDataFormatException * is thrown. Otherwise, the group is converted to the character:

*


     * (char)(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F))
     * 
* If the first byte of a group matches the pattern 1111xxxx or the pattern 10xxxxxx, then * a UTFDataFormatException is thrown. *

* If end of file is encountered at any time during this entire process, then an EOFException is * thrown. *

* After every group has been converted to a character by this process, the characters are gathered, in the same * order in which their corresponding groups were read from the input stream, to form a String, which * is returned. *

* The writeUTF method of interface DataOutput may be used to write data that is suitable * for reading by this method. * * @return a Unicode string. * @throws IllegalStateException if the bytes do not represent a valid modified UTF-8 encoding of a string. */ @Override @NotNull String readUTF(); /** * The same as readUTF() except the length is stop bit encoded. This saves one byte for strings shorter than 128 * chars. null values are also supported * * @return a Unicode string or null if writeUTFΔ(null) was called */ @Nullable String readUTFΔ(); /** * The same as readUTFΔ() except an offset and maximum length is given. * * @param offset to read from * @return a Unicode string or null if writeUTFΔ(null) was called * @throws IllegalStateException if the length to be read is out of range. */ @Nullable String readUTFΔ(long offset) throws IllegalStateException; /** * The same as readUTFΔ() except the chars are copied to a truncated StringBuilder. * * @return true if there was a String, or false if it was null */ boolean readUTFΔ(@NotNull StringBuilder stringBuilder); /** * Copy bytes into a ByteBuffer to the minimum of the length remaining() in the ByteBuffer or the * Excerpt. * * @param bb to copy into */ void read(@NotNull ByteBuffer bb); /** * Read a String with readUTFΔ which is converted to an enumerable type. i.e. where there is a one to * one mapping between an object and it's toString(). *

* This is suitable to read an object written using writeEnum() in the RandomDataOutput * interface * * @param eClass to decode the String as * @return the decoded value. null with be return if null was written. */ @Nullable E readEnum(@NotNull Class eClass); /** * Read a stop bit encoded length and populates this Collection after clear()ing it. *

* This is suitable to reading a list written using writeList() in the RandomDataOutput * interface * * @param list to populate */ void readList(@NotNull Collection list, @NotNull Class eClass); /** * Read a stop bit encoded length and populates this Map after clear()ing it. *

* This is suitable to reading a list written using writeMap() in the RandomDataOutput * interface * * @param map to populate * @return the map */ Map readMap(@NotNull Map map, @NotNull Class kClass, @NotNull Class vClass); // ObjectInput /** * Read and return an object. The class that implements this interface defines where the object is "read" from. * * @return the object read from the stream * @throws IllegalStateException the class of a serialized object cannot be found or any of the usual Input/Output * related exceptions occur. */ @Nullable @Override Object readObject() throws IllegalStateException; /** * Read and return an object. The class that implements this interface defines where the object is "read" from. * * @return the object read from the stream * @throws IllegalStateException the class of a serialized object cannot be found or any of the usual Input/Output * related exceptions occur. * @throws ClassCastException The class cannot be cast or converted to the type given. */ @Nullable T readObject(Class tClass) throws IllegalStateException; /** * Reads a byte of data. This method will block if no input is available. * * @return the byte read, or -1 if the end of the stream is reached. */ @Override int read(); /** * Reads into an array of bytes. This method will block until some input is available. * * @param bytes the buffer into which the data is read * @return the actual number of bytes read, -1 is returned when the end of the stream is reached. */ @Override int read(@NotNull byte[] bytes); /** * Reads into an array of bytes. This method will block until some input is available. * * @param bytes the buffer into which the data is read * @param off the start offset of the data * @param len the maximum number of bytes read * @return the actual number of bytes read, -1 is returned when the end of the stream is reached. */ @Override int read(@NotNull byte[] bytes, int off, int len); /** * Read the object from start to end bytes * * @param object to read into * @param start byte inclusive * @param end byte exclusive */ void readObject(Object object, int start, int end); /** * Skips n bytes of input. * * @param n the number of bytes to be skipped * @return the actual number of bytes skipped. */ @Override long skip(long n); /** * @return remaining() or Integer.MAX_VALUE if larger. */ @Override int available(); /** * Finishes the excerpt entry if not finished() */ @Override void close(); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/RandomDataOutput.java000077500000000000000000001112371226752375100265400ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.ObjectOutput; import java.nio.ByteBuffer; import java.util.Collection; import java.util.Map; import java.util.RandomAccess; /** * @author peter.lawrey */ public interface RandomDataOutput extends ObjectOutput, RandomAccess, BytesCommon { /** * Copy from one Bytes to another. Copied from the start to the current position. * * @param bytes to copy from * @deprecated Use write(BytesCommon bytes, long position, long length) instead. */ @Deprecated void writeStartToPosition(Bytes bytes); /** * Writes to the output stream the eight low-order bits of the argument b. The 24 high-order bits of * b are ignored. * * @param b the byte to be written. */ @Override void write(int b); /** * Writes to the output stream the eight low- order bits of the argument v. The 24 high-order bits of * v are ignored. (This means that writeByte does exactly the same thing as * write for an integer argument.) The byte written by this method may be read by the * readByte method of interface DataInput, which will then return a byte * equal to (byte)v. * * @param v the byte value to be written. */ @Override void writeByte(int v); /** * Writes to the output stream the eight low- order bits of the argument v. The 24 high-order bits of * v are ignored. (This means that writeByte does exactly the same thing as * write for an integer argument.) The byte written by this method may be read by the * readUnsignedByte method of interface DataInput, which will then return a * byte equal to (byte)v. * * @param v the byte value to be written. */ void writeUnsignedByte(int v); /** * Writes to the output stream the eight low-order bits of the argument b. The 24 high-order bits of * b are ignored. * * @param offset to write byte * @param b the byte to be written. */ void writeByte(long offset, int b); /** * Writes to the output stream the eight low- order bits of the argument v. The 24 high-order bits of * v are ignored. (This means that writeByte does exactly the same thing as * write for an integer argument.) The byte written by this method may be read by the * readUnsignedByte method of interface DataInput, which will then return a * byte equal to v & 0xFF. * * @param offset to write byte * @param v the unsigned byte value to be written. */ void writeUnsignedByte(long offset, int v); /** * Writes to the output stream all the bytes in array bytes. If bytes is * null, a NullPointerException is thrown. If bytes.length is zero, then no * bytes are written. Otherwise, the byte bytes[0] is written first, then bytes[1], and so * on; the last byte written is bytes[bytes.length-1]. * * @param bytes the data. */ @Override void write(byte[] bytes); /** * Writes to the output stream all the bytes in array bytes. If bytes is * null, a NullPointerException is thrown. If bytes.length is zero, then no * bytes are written. Otherwise, the byte bytes[0] is written first, then bytes[1], and so * on; the last byte written is bytes[bytes.length-1]. * * @param offset to be written * @param bytes the data. */ void write(long offset, byte[] bytes); /** * Writes len bytes from array bytes, in order, to the output stream. If * bytes is null, a NullPointerException is thrown. If off is * negative, or len is negative, or off+len is greater than the length of the array * bytes, then an IndexOutOfBoundsException is thrown. If len is zero, then * no bytes are written. Otherwise, the byte bytes[off] is written first, then * bytes[off+1], and so on; the last byte written is bytes[off+len-1]. * * @param bytes the data. * @param off the start offset in the data. * @param len the number of bytes to write. */ @Override void write(byte[] bytes, int off, int len); /** * Writes a boolean value to this output stream. If the argument v is true, * the value (byte)1 is written; if v is false, the value * (byte)0 is written. The byte written by this method may be read by the readBoolean * method of interface DataInput, which will then return a boolean equal to * v. * * @param v the boolean to be written. */ @Override void writeBoolean(boolean v); /** * Writes a boolean value to this output stream. If the argument v is true, * the value (byte)1 is written; if v is false, the value * (byte)0 is written. The byte written by this method may be read by the readBoolean * method of interface DataInput, which will then return a boolean equal to * v. * * @param offset to write boolean * @param v the boolean to be written. */ void writeBoolean(long offset, boolean v); /** * Writes two bytes to the output stream to represent the value of the argument. The byte values to be written, in * the order shown for big endian machines and the opposite for little endian, are:

*


     * (byte)(0xff & (v >> 8))
     * (byte)(0xff & v)
     *  

* The bytes written by this method may be read by the readShort method of interface * DataInput , which will then return a short equal to (short)v. * * @param v the short value to be written. */ @Override void writeShort(int v); /** * Writes two bytes to the output stream to represent the value of the argument. The byte values to be written, in * the order shown for big endian machines and the opposite for little endian, are:

*


     * (byte)(0xff & (v >> 8))
     * (byte)(0xff & v)
     *  

* The bytes written by this method may be read by the readShort method of interface * DataInput , which will then return a short equal to (short)v. * * @param offset to be written to * @param v the short value to be written. */ void writeShort(long offset, int v); /** * Writes two bytes to the output stream to represent the value of the argument. The byte values to be written, in * the order shown for big endian machines and the opposite for little endian, are:

*


     * (byte)(0xff & (v >> 8))
     * (byte)(0xff & v)
     *  

* The bytes written by this method may be read by the readUnsignedShort method of interface * RandomDataInput , which will then return a short equal to (short)v. * * @param v the unsigned short value to be written. */ void writeUnsignedShort(int v); /** * Writes two bytes to the output stream to represent the value of the argument. The byte values to be written, in * the order shown for big endian machines and the opposite for little endian, are:

*


     * (byte)(0xff & (v >> 8))
     * (byte)(0xff & v)
     *  

* The bytes written by this method may be read by the readShort method of interface * RandomDataInput , which will then return a short equal to (short)v. * * @param offset to be written to * @param v the unsigned short value to be written. */ void writeUnsignedShort(long offset, int v); /** * Writes one or three bytes as follows; Short.MIN_VALUE => Byte.MIN_VALUE, Short.MAX_VALUE => Byte.MAX_VALUE, * Short.MIN_VALUE+2 to Short.MAX_VALUE-1 => writeByte(x), default => writeByte(Byte.MIN_VALUE+1; * writeShort(x) *

* The bytes written by this method may be read by the readCompactShort method of interface * RandomDataInput , which will then return a short equal to (short)v. * * @param v the short value to be written. */ void writeCompactShort(int v); /** * Writes one or three bytes as follows; 0 to 254 => writeByte(x); otherwise writeByte(255); writeByteShort(x); *

* The bytes written by this method may be read by the readCompactUnsignedShort method of interface * RandomDataInput , which will then return a short equal to v & 0xFFFF. * * @param v the unsigned short value to be written. */ void writeCompactUnsignedShort(int v); /** * Writes a char value, which is comprised of two bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readChar method of interface * DataInput , which will then return a char equal to (char)v. * * @param v the char value to be written. */ @Override void writeChar(int v); /** * Writes a char value, which is comprised of two bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readChar method of interface * DataInput , which will then return a char equal to (char)v. * * @param offset to be written to * @param v the char value to be written. */ void writeChar(long offset, int v); /** * Writes an int value, which is comprised of three bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>    8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readInt24 method of interface * RandomDataInput , which will then return an int equal to v. * * @param v the int value to be written. */ void writeInt24(int v); /** * Writes an int value, which is comprised of three bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>    8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readInt24 method of interface * RandomDataInput , which will then return an int equal to v. * * @param offset to be written to * @param v the int value to be written. */ void writeInt24(long offset, int v); /** * Writes an int value, which is comprised of four bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>    8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readInt method of interface * DataInput , which will then return an int equal to v. * * @param v the int value to be written. */ @Override void writeInt(int v); /** * Writes an int value, which is comprised of four bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>    8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readInt method of interface * DataInput , which will then return an int equal to v. * * @param offset to be written to * @param v the int value to be written. */ void writeInt(long offset, int v); /** * Writes an int value, which is comprised of four bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>    8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readUnsignedInt method of interface * RandomDataInput , which will then return an long equal to v & * 0xFFFFFFFF. * * @param v the int value to be written. */ void writeUnsignedInt(long v); /** * Writes an int value, which is comprised of four bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>    8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readUnsignedInt method of interface * RandomDataInput , which will then return an long equal to v & * 0xFFFFFFFF. * * @param offset to be written to * @param v the int value to be written. */ void writeUnsignedInt(long offset, long v); /** * Writes two or six bytes as follows; Integer.MIN_VALUE => Short.MIN_VALUE, Integer.MAX_VALUE => * Short.MAX_VALUE, Short.MIN_VALUE+2 to Short.MAX_VALUE-1 => writeShort(x), default => * writeShort(Short.MIN_VALUE+1; writeInt(x) *

* The bytes written by this method may be read by the readCompactInt method of interface * RandomDataInput , which will then return a int equal to v. * * @param v the int value to be written. */ void writeCompactInt(int v); /** * Writes two or six bytes as follows; 0 to (1 << 16) - 2 => writeInt(x), otherwise writeShort(-1); * writeInt(x) *

* The bytes written by this method may be read by the readCompactUnsignedInt method of interface * RandomDataInput , which will then return a int equal to v & * 0xFFFFFFFF. * * @param v the short value to be written. */ void writeCompactUnsignedInt(long v); /** * Same as writeInt but include an ordered write barrier. This means all writes will be visible on a read barrier * if this write is visible. This might not be visible to be same thread for some clock cycles so an immediate read * could see an old value *

* This is much faster than a volatile write which stalls the pipeline. The data is visible to other threads at the * same time. * * @param v value to write */ void writeOrderedInt(int v); /** * Same as writeInt but include an ordered write barrier. This means all writes will be visible on a read barrier * if this write is visible. This might not be visible to be same thread for some clock cycles so an immediate read * could see an old value *

* This is much faster than writeVolatileInt as the volatile write stalls the pipeline. The data is * visible to other threads at the same time. * * @param offset to write to * @param v value to write */ void writeOrderedInt(long offset, int v); /** * Perform a compare and set operation. The value is set to x provided the expected value * is set already. This operation is atomic. * * @param offset to write to. * @param expected to expect * @param x to set if expected was found * @return true if set, false if the value was not expected */ boolean compareAndSwapInt(long offset, int expected, int x); /** * Atomically adds the given value to the current value. * * @param offset of the int value to use. * @param delta the value to add * @return the previous value */ int getAndAdd(long offset, int delta); /** * Atomically adds the given value to the current value. * * @param offset of the int value to use. * @param delta the value to add * @return the updated value */ int addAndGetInt(long offset, int delta); /** * Writes a long value, which is comprised of eight bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 40))
     * (byte)(0xff & (v >> 32))
     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>  8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readInt48 method of interface * RandomDataInput , which will then return a long equal to v & ((1L << 48) * - 1). * * @param v the long value to be written. */ void writeInt48(long v); /** * Writes a long value, which is comprised of eight bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 40))
     * (byte)(0xff & (v >> 32))
     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>  8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readInt48 method of interface * RandomDataInput , which will then return a long equal to v & ((1L << 48) * - 1). * * @param offset to be written to * @param v the long value to be written. */ void writeInt48(long offset, long v); /** * Writes a long value, which is comprised of eight bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 56))
     * (byte)(0xff & (v >> 48))
     * (byte)(0xff & (v >> 40))
     * (byte)(0xff & (v >> 32))
     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>  8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readLong method of interface * DataInput , which will then return a long equal to v. * * @param v the long value to be written. */ @Override void writeLong(long v); /** * Writes a long value, which is comprised of eight bytes, to the output stream. The byte values to be * written, in the order shown for big endian machines and the opposite for little endian, are: *


     * (byte)(0xff & (v >> 56))
     * (byte)(0xff & (v >> 48))
     * (byte)(0xff & (v >> 40))
     * (byte)(0xff & (v >> 32))
     * (byte)(0xff & (v >> 24))
     * (byte)(0xff & (v >> 16))
     * (byte)(0xff & (v >>  8))
     * (byte)(0xff & v)
     * 

* The bytes written by this method may be read by the readLong method of interface * DataInput , which will then return a long equal to v. * * @param offset to be written to * @param v the long value to be written. */ void writeLong(long offset, long v); /** * Writes four or twelve bytes as follows Long.MIN_VALUE => Integer.MIN_VALUE, Long.MAX_VALUE => * Integer.MAX_VALUE, Integer.MIN_VALUE+2 to Integer.MAX_VALUE-1 => writeInt(x), default => * writeInt(Integer.MIN_VALUE+1; writeLong(x) *

* The bytes written by this method may be read by the readCompactLong method of interface * RandomDataInput , which will then return a long equal to v. * * @param v the long value to be written. */ void writeCompactLong(long v); /** * Same as writeLong but include an ordered write barrier. This means all writes will be visible on a read barrier * if this write is visible. This might not be visible to be same thread for some clock cycles so an immediate read * could see an old value *

* This is much faster than a volatile write which stalls the pipeline. The data is visible to other threads at the * same time. * * @param v value to write */ void writeOrderedLong(long v); /** * Same as writeLong but include an ordered write barrier. This means all writes will be visible on a read barrier * if this write is visible. This might not be visible to be same thread for some clock cycles so an immediate read * could see an old value *

* This is much faster than a volatile write which stalls the pipeline. The data is visible to other threads at the * same time. * * @param offset to be written to * @param v value to write */ void writeOrderedLong(long offset, long v); /** * Perform a compare and set operation. The value is set to x provided the expected value * is set already. This operation is atomic. * * @param offset to write to. * @param expected to expect * @param x to set if expected was found * @return true if set, false if the value was not expected */ boolean compareAndSwapLong(long offset, long expected, long x); /** * Stop bit encoding numbers. This will write the same number of bytes whether you used a byte, short or int. */ void writeStopBit(long n); /** * Writes a float value, which is comprised of four bytes, to the output stream. It does this as if it * first converts this float value to an int in exactly the manner of the * Float.floatToIntBits method and then writes the int value in exactly the manner of the * writeInt method. The bytes written by this method may be read by the readFloat method * of interface DataInput, which will then return a float equal to v. * * @param v the float value to be written. */ @Override void writeFloat(float v); /** * Writes a float value, which is comprised of four bytes, to the output stream. It does this as if it * first converts this float value to an int in exactly the manner of the * Float.floatToIntBits method and then writes the int value in exactly the manner of the * writeInt method. The bytes written by this method may be read by the readFloat method * of interface DataInput, which will then return a float equal to v. * * @param offset to write to * @param v the float value to be written. */ void writeFloat(long offset, float v); /** * Same as writeFloat but include an ordered write barrier. This means all writes will be visible on a read barrier * if this write is visible. This might not be visible to be same thread for some clock cycles so an immediate read * could see an old value *

* This is much faster than a volatile write which stalls the pipeline. The data is visible to other threads at the * same time. * * @param v value to write */ void writeOrderedFloat(long offset, float v); /** * Writes a double value, which is comprised of eight bytes, to the output stream. It does this as if * it first converts this double value to a long in exactly the manner of the * Double.doubleToLongBits method and then writes the long value in exactly the manner of * the writeLong method. The bytes written by this method may be read by the readDouble * method of interface DataInput, which will then return a double equal to * v. * * @param v the double value to be written. */ @Override void writeDouble(double v); /** * Writes a double value, which is comprised of eight bytes, to the output stream. It does this as if * it first converts this double value to a long in exactly the manner of the * Double.doubleToLongBits method and then writes the long value in exactly the manner of * the writeLong method. The bytes written by this method may be read by the readDouble * method of interface DataInput, which will then return a double equal to * v. * * @param offset to write to * @param v the double value to be written. */ void writeDouble(long offset, double v); /** * Writes four or twelve bytes as follow; *


     * if ((float) d == d) {
     *     writeFloat((float) d);
     * } else {
     *     writeFloat(Float.NaN);
     *     writeDouble(d);
     * }
     * 

* The bytes written by this method may be read by the readCompactDouble method of interface * RandomDataInput , which will then return a double equal to v. * * @param v the double value to be written. */ void writeCompactDouble(double v); /** * Same as writeDouble but include an ordered write barrier. This means all writes will be visible on a read * barrier if this write is visible. This might not be visible to be same thread for some clock cycles so an * immediate read could see an old value *

* This is much faster than a volatile write which stalls the pipeline. The data is visible to other threads at the * same time. * * @param v value to write */ void writeOrderedDouble(long offset, double v); /** * Writes a string to the output stream. For every character in the string s, taken in order, one byte * is written to the output stream. If s is null, a NullPointerException is * thrown.

If s.length is zero, then no bytes are written. Otherwise, the character * s[0] is written first, then s[1], and so on; the last character written is * s[s.length-1]. For each character, one byte is written, the low-order byte, in exactly the manner of * the writeByte method . The high-order eight bits of each character in the string are ignored. * * @param s the string of bytes to be written. Cannot be null. */ @Override void writeBytes(@NotNull String s); /** * Writes every character in the string s, to the output stream, in order, two bytes per character. If * s is null, a NullPointerException is thrown. If s.length is * zero, then no characters are written. Otherwise, the character s[0] is written first, then * s[1], and so on; the last character written is s[s.length-1]. For each character, two * bytes are actually written, high-order byte first, in exactly the manner of the writeChar method. * * @param s the string value to be written. Cannot be null. */ @Override void writeChars(@NotNull String s); /** * Writes two bytes of length information to the output stream, followed by the modified UTF-8 representation of every character in the string * s. If s is null, a NullPointerException is thrown. Each * character in the string s is converted to a group of one, two, or three bytes, depending on the * value of the character.

If a character c is in the range \u0001 through * \u007f, it is represented by one byte:

*

(byte)c 

* If a character c is \u0000 or is in the range \u0080 through * \u07ff, then it is represented by two bytes, to be written * in the order shown:


     * (byte)(0xc0 | (0x1f & (c >> 6)))
     * (byte)(0x80 | (0x3f & c))
     *  

If a character * c is in the range \u0800 through uffff, then it is represented by * three bytes, to be written * in the order shown:


     * (byte)(0xe0 | (0x0f & (c >> 12)))
     * (byte)(0x80 | (0x3f & (c >>  6)))
     * (byte)(0x80 | (0x3f & c))
     *  

First, * the total number of bytes needed to represent all the characters of s is calculated. If this number * is larger than 65535, then a UTFDataFormatException is thrown. Otherwise, this length * is written to the output stream in exactly the manner of the writeShort method; after this, the * one-, two-, or three-byte representation of each character in the string s is written.

The bytes * written by this method may be read by the readUTF method of interface DataInput , which * will then return a String equal to s. * * @param s the string value to be written. Cannot be null */ @Override void writeUTF(@NotNull String s); /** * Write the same encoding as writeUTF with the following changes. 1) The length is stop bit encoded * i.e. one byte longer for short strings, but is not limited in length. 2) The string can be null. * * @param s the string value to be written. Can be null. */ void writeUTFΔ(@Nullable CharSequence s); /** * Write the same encoding as writeUTF with the following changes. 1) The length is stop bit encoded * i.e. one byte longer for short strings, but is not limited in length. 2) The string can be null. * * @param offset to write to * @param maxSize maximum number of bytes to use * @param s the string value to be written. Can be null. * @throws IllegalStateException if the size is too large. */ void writeUTFΔ(long offset, int maxSize, @Nullable CharSequence s) throws IllegalStateException; /** * Copies the contents of a ByteBuffer from the potision ot the limit. * * @param bb to copy. */ void write(@NotNull ByteBuffer bb); /** * Write the object in a form which can be uniquely recreated by readEnum. This type of "enumerable objects" has * the following constraints; 1) each object must have a one to one mapping with a toString() representation, 2) be * immutable, 3) ideally appears more than once, 4) Must have a constructor which takes a single String or a * valueOf(String) method. * * @param e to enumerate * @param element class */ void writeEnum(@Nullable E e); /** * Write an ordered collection of "enumerable objects" (See writeEnum). This writes the stop bit encoded length, * followed by multiple calls to writeEnum All the elements must be of the same type. *

* This can be read by the readList method of RandomInputStream and the reader must know * the type of each element. You can send the class first by using writeEnum of the element class * * @param list to be written */ void writeList(@NotNull Collection list); /** * Write the keys and values of a Map of "enumerable objects" (See writeEnum). This writes the stop bit encoded * length, followed by multiple calls to writeEnum for each key and value. All the keys must be of the * same type. All values must be of the same type. * * @param map to write out */ void writeMap(@NotNull Map map); // ObjectOutput /** * Write an object as either an "enumerable object" or a Serializable/Externalizable object using Java * Serialization. Java Serialization is much slower but sometimes more convenient than using * BytesMarshallable. * * @param object to write */ @Override void writeObject(@Nullable Object object); /** * Copy data from an Object from bytes start to end. * * @param object to copy from * @param start first byte inclusive * @param end last byte exclusive. */ void writeObject(Object object, int start, int end); /** * Check the end of the stream has not overflowed. Otherwise this doesn't do anything. */ @Override void flush(); /** * The same as calling finish(); */ @Override void close(); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/RandomDataUpdate.java000066400000000000000000000126711226752375100264610ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; /** * This class supports updates which are a companion to RandomDataInput and RandomDataOutput */ public interface RandomDataUpdate { byte addByte(long offset, byte b); int addUnsignedByte(long offset, int i); short addShort(long offset, short s); int addUnsignedShort(long offset, int i); int addInt(long offset, int i); long addUnsignedInt(long offset, long i); long addLong(long offset, long i); float addFloat(long offset, float f); double addDouble(long offset, double d); int addAtomicInt(long offset, int i); long addAtomicLong(long offset, long l); float addAtomicFloat(long offset, float f); double addAtomicDouble(long offset, double d); /** * Lock which uses 4 bytes. It store the lower 24 bits of the Thread Id and the re-entrant count as 8 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 255 times * you will get an ISE * * @param offset of the start of the 4-byte lock * @return did it lock or not. */ boolean tryLockInt(long offset); /** * Lock which uses 4 bytes. It store the lower 24 bits of the Thread Id and the re-entrant count as 8 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 255 times * you will get an ISE * * @param offset of the start of the 4-byte lock * @param nanos to try to lock for * @return did it lock or not. */ boolean tryLockNanosInt(long offset, long nanos); /** * Lock which uses 4 bytes. It store the lower 24 bits of the Thread Id and the re-entrant count as 8 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 255 times * you will get an ISE * * @param offset of the start of the 4-byte lock * @throws InterruptedException if interrupted * @throws IllegalStateException if the thread tries to lock it 255 nested time (without an unlock) */ void busyLockInt(long offset) throws InterruptedException, IllegalStateException; /** * Lock which uses 4 bytes. Unlock this It store the lower 24 bits of the Thread Id and the re-entrant count as 8 * bit. This means if you create more than 16 million threads you can get a collision, and if you try to re-enter * 255 times you will get an ISE * * @param offset of the start of the 4-byte lock * @throws IllegalMonitorStateException if this thread doesn't hold the lock */ void unlockInt(long offset) throws IllegalMonitorStateException; /** * Lock across processes *

* Lock which uses 8 bytes. It store the lower 32 bits of the Thread Id, 16 bits are the process id and the re-entrant count as 16 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 65535 times * you will get an ISE * * @param offset of the start of the 8-byte lock * @return did it lock or not. */ boolean tryLockLong(long offset); /** * Lock across processes *

* Lock which uses 8 bytes. It store the lower 32 bits of the Thread Id, 16 bits are the process id and the re-entrant count as 16 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 65535 times * you will get an ISE * * @param offset of the start of the 8-byte lock * @param nanos to try to lock for * @return did it lock or not. */ boolean tryLockNanosLong(long offset, long nanos); /** * Lock across processes *

* Lock which uses 8 bytes. It store the lower 32 bits of the Thread Id, 16 bits are the process id and the re-entrant count as 16 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 65535 times * you will get an ISE * * @param offset of the start of the 8-byte lock * @throws InterruptedException if interrupted * @throws IllegalStateException if the thread tries to lock it 65535 nested time (without an unlock) */ void busyLockLong(long offset) throws InterruptedException, IllegalStateException; /** * Lock across processes *

* Lock which uses 8 bytes. It store the lower 32 bits of the Thread Id, 16 bits are the process id and the re-entrant count as 16 bit. This * means if you create more than 16 million threads you can get a collision, and if you try to re-enter 65535 times * you will get an ISE * * @param offset of the start of the 8-byte lock * @throws IllegalMonitorStateException if this thread doesn't hold the lock */ void unlockLong(long offset) throws IllegalMonitorStateException; } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/StopCharTester.java000077500000000000000000000022761226752375100262210ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; /** * @author peter.lawrey */ public interface StopCharTester { /** * Detect which byte stops the string to be parsed *

* This should be changed to support char instead. *

* Note: for safety reasons, you should stop on a 0 byte or throw an IllegalStateException. * * @param ch to test, 0 should return true or throw an exception. * @return if this byte is a stop character. * @throws IllegalStateException if an invalid character like 0 was detected. */ boolean isStopChar(int ch) throws IllegalStateException; } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/StopCharTesters.java000077500000000000000000000045621226752375100264040ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; /** * @author peter.lawrey */ public enum StopCharTesters implements StopCharTester { COMMA_STOP { @Override public boolean isStopChar(int ch) { return ch < ' ' || ch == ','; } }, CONTROL_STOP { @Override public boolean isStopChar(int ch) { return ch < ' '; } }, SPACE_STOP { @Override public boolean isStopChar(int ch) { return Character.isWhitespace(ch) || ch == 0; } }, XML_TEXT { @Override public boolean isStopChar(int ch) { return ch == '"' || ch == '<' || ch == '>' || ch == 0; } }, FIX_TEXT { @Override public boolean isStopChar(int ch) { return ch <= 1; } }; @NotNull public static StopCharTester forChars(@NotNull CharSequence sequence) { if (sequence.length() == 1) return forChar(sequence.charAt(0)); return new CSCSTester(sequence); } @NotNull public static StopCharTester forChar(char ch) { return new CharCSTester(ch); } static class CSCSTester implements StopCharTester { @NotNull private final String seperators; public CSCSTester(@NotNull CharSequence cs) { seperators = cs.toString(); } @Override public boolean isStopChar(int ch) { return seperators.indexOf(ch) >= 0; } } static class CharCSTester implements StopCharTester { private final char ch; public CharCSTester(char ch) { this.ch = ch; } @Override public boolean isStopChar(int ch) { return this.ch == ch; } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/000077500000000000000000000000001226752375100253075ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/BytesMarshallable.java000066400000000000000000000023071226752375100315520ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.Bytes; import org.jetbrains.annotations.NotNull; /** * Integrated marshaller for objects. * * @author peter.lawrey * @see BytesMarshaller */ public interface BytesMarshallable { /** * read an object from bytes * * @param in to read from * @throws IllegalStateException if the object could not be read. */ void readMarshallable(@NotNull Bytes in) throws IllegalStateException; /** * write an object to bytes * * @param out to write to */ void writeMarshallable(@NotNull Bytes out); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/BytesMarshaller.java000066400000000000000000000022241226752375100312530ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.Bytes; import org.jetbrains.annotations.Nullable; /** * External marshaller for classes. * * @author peter.lawrey * @see BytesMarshallable */ public interface BytesMarshaller { /** * write the object out as bytes. * * @param bytes to write to * @param e to write */ void write(Bytes bytes, E e); /** * Read bytes and obtain an object * * @param bytes to read * @return the object */ @Nullable E read(Bytes bytes); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/BytesMarshallerFactory.java000066400000000000000000000017441226752375100326110ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import org.jetbrains.annotations.NotNull; /** * @author peter.lawrey */ public interface BytesMarshallerFactory { @NotNull BytesMarshaller acquireMarshaller(@NotNull Class eClass, boolean create); BytesMarshaller getMarshaller(byte code); void addMarshaller(Class eClass, BytesMarshaller marshaller); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/CompactBytesMarshaller.java000066400000000000000000000015211226752375100325610ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; /** * A BytesMarshaller with a byte code for the class. */ public interface CompactBytesMarshaller extends BytesMarshaller { /** * the code for this marshaller */ byte code(); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/RawCopier.java000066400000000000000000000062231226752375100300500ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.Bytes; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import static net.openhft.lang.io.NativeBytes.UNSAFE; /** * User: peter.lawrey Date: 22/09/13 Time: 16:51 */ public class RawCopier { final int start, end; private final Class tClass; public RawCopier(Class tClass) { this.tClass = tClass; List fields = new ArrayList(); addAllFields(fields, tClass); Collections.sort(fields, new Comparator() { @Override public int compare(Field o1, Field o2) { long off1 = UNSAFE.objectFieldOffset(o1); long off2 = UNSAFE.objectFieldOffset(o2); return Double.compare(off1, off2); } }); start = (int) UNSAFE.objectFieldOffset(fields.get(0)); Field lastField = null; for (Field field : fields) { if (Modifier.isTransient(field.getModifiers()) || !field.getType().isPrimitive()) break; lastField = field; } end = (int) UNSAFE.objectFieldOffset(lastField) + sizeOf(lastField.getType()); assert end > start : "end <= start, start: " + start + ", end: " + end; } public static RawCopier copies(Class tClass) { return new RawCopier(tClass); } private static int sizeOf(Class type) { return UNSAFE.arrayIndexScale(Array.newInstance(type, 0).getClass()); } public int start() { return start; } public int end() { return end; } public void toBytes(Object obj, Bytes bytes) { bytes.writeObject(obj, start, end); } public void fromBytes(Bytes bytes, Object obj) { bytes.readObject(obj, start, end); } public void copy(T from, T to) { long i; for (i = start; i < end - 7; i += 8) { UNSAFE.putLong(to, i, UNSAFE.getLong(from, i)); } for (; i < end; i++) { UNSAFE.putByte(to, i, UNSAFE.getByte(from, i)); } } private void addAllFields(List fields, Class tClass) { if (tClass != null && tClass != Object.class) addAllFields(fields, tClass.getSuperclass()); for (Field field : tClass.getDeclaredFields()) { if (!Modifier.isStatic(field.getModifiers())) fields.add(field); } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/direct/000077500000000000000000000000001226752375100265615ustar00rootroot00000000000000DirectSerializationFilter.java000066400000000000000000000015011226752375100344600ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/directpackage net.openhft.lang.io.serialization.direct; import java.lang.reflect.Field; import java.util.*; import static net.openhft.lang.io.serialization.direct.FieldMetadata.*; public final class DirectSerializationFilter { public static List stopAtFirstIneligibleField(List fields) { ArrayList eligibleFields = new ArrayList(); for (Field f : fields) { if (checkEligible(f)) { eligibleFields.add(f); } else { break; } } return eligibleFields.isEmpty() ? Collections.emptyList() : eligibleFields; } private static boolean checkEligible(Field f) { return isPrimitive(f) && !isStatic(f) && !isTransient(f); } }DirectSerializationMetadata.java000066400000000000000000000060651226752375100347650ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/directpackage net.openhft.lang.io.serialization.direct; import net.openhft.lang.Jvm; import java.lang.reflect.Field; import java.util.List; import static net.openhft.lang.io.NativeBytes.UNSAFE; public class DirectSerializationMetadata { private static final int OBJECT_ALIGNMENT = 8; private static final int OBJECT_ALIGNMENT_MASK = OBJECT_ALIGNMENT - 1; static final long NATIVE_WORD_SIZE = Jvm.is64Bit() ? 8 : 4; static final long OOP_SIZE = UNSAFE.arrayIndexScale(Object[].class); static final long OBJECT_HEADER_SIZE = NATIVE_WORD_SIZE + OOP_SIZE; // Object header has a native sized mark word + variable sized oop to klass meta object public static final SerializationMetadata EmptyObjectMetadata = new SerializationMetadata(0, 0); public static final class SerializationMetadata { final long start; final long length; SerializationMetadata(long start, long length) { this.start = start; this.length = length; } @Override public String toString() { return String.format("SerializationMetadata: Start %s Length %s", start, length); } } public static SerializationMetadata extractMetadata(List fields) { if (fields.isEmpty()) return EmptyObjectMetadata; Offsets offsets = minMaxOffsets(fields); long totalSize = OBJECT_HEADER_SIZE + offsets.max - offsets.min + 1; return new SerializationMetadata(offsets.min, padToObjectAlignment(totalSize) - OBJECT_HEADER_SIZE); } public static SerializationMetadata extractMetadataForPartialCopy(List fields) { if (fields.isEmpty()) return EmptyObjectMetadata; Offsets offsets = minMaxOffsets(fields); Field lastField = fields.get(fields.size() - 1); return new SerializationMetadata(offsets.min, offsets.max + sizeOf(lastField) - OBJECT_HEADER_SIZE); } private static Offsets minMaxOffsets(List fields) { long minOffset = UNSAFE.objectFieldOffset(fields.get(0)); long maxOffset = UNSAFE.objectFieldOffset(fields.get(fields.size() - 1)); return new Offsets(minOffset, maxOffset); } static long padToObjectAlignment(long length) { if ((length & OBJECT_ALIGNMENT_MASK) != 0) { long padding = OBJECT_ALIGNMENT - (length & OBJECT_ALIGNMENT_MASK); length += padding; } return length; } private static long sizeOf(Field field) { if (boolean.class.equals(field.getType())) return 1; else if (byte.class.equals(field.getType())) return 1; else if (short.class.equals(field.getType())) return 2; else if (char.class.equals(field.getType())) return 2; else if (int.class.equals(field.getType())) return 4; else if (float.class.equals(field.getType())) return 4; else return 8; } private static final class Offsets { public final long min; public final long max; private Offsets(long min, long max) { this.min = min; this.max = max; } } }Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/direct/FieldMetadata.java000066400000000000000000000011331226752375100321060ustar00rootroot00000000000000package net.openhft.lang.io.serialization.direct; import java.lang.reflect.*; public final class FieldMetadata { public static boolean isPrimitive(Field f) { return f.getType().isPrimitive(); } public static boolean isPrimitiveArray(Field f) { Class clazz = f.getType(); return clazz.isArray() && clazz.getComponentType().isPrimitive(); } public static boolean isStatic(Field f) { return Modifier.isStatic(f.getModifiers()); } public static boolean isTransient(Field f) { return Modifier.isTransient(f.getModifiers()); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/direct/Introspect.java000066400000000000000000000040761226752375100315650ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.direct; import net.openhft.lang.Maths; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import static net.openhft.lang.io.NativeBytes.UNSAFE; import static net.openhft.lang.io.serialization.direct.FieldMetadata.isStatic; public class Introspect { public static List fields(Class clazz) { ArrayList fields = new ArrayList(); addToFields(clazz, fields); Collections.sort(fields, FieldOffsetComparator.Instance); return fields; } private static List addToFields(Class clazz, ArrayList accumulator) { Collections.addAll(accumulator, clazz.getDeclaredFields()); Class maybeSuper = clazz.getSuperclass(); return maybeSuper != null ? addToFields(maybeSuper, accumulator) : accumulator; } private static final class FieldOffsetComparator implements Comparator { public static final FieldOffsetComparator Instance = new FieldOffsetComparator(); @Override public int compare(Field first, Field second) { return Maths.compare(offset(first), offset(second)); } private static long offset(Field field) { return isStatic(field) ? UNSAFE.staticFieldOffset(field) : UNSAFE.objectFieldOffset(field); } } }Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/direct/ObjectMarshaller.java000066400000000000000000000023671226752375100326550ustar00rootroot00000000000000package net.openhft.lang.io.serialization.direct; import net.openhft.lang.io.Bytes; import static net.openhft.lang.io.NativeBytes.UNSAFE; import static net.openhft.lang.io.serialization.direct.DirectSerializationMetadata.SerializationMetadata; public final class ObjectMarshaller { private final SerializationMetadata metadata; public ObjectMarshaller(SerializationMetadata metadata) { this.metadata = metadata; } public void write(Bytes bytes, T tObject) { long i = metadata.start; long end = metadata.start + metadata.length; while (i < end - 7) { bytes.writeLong(UNSAFE.getLong(tObject, i)); i += 8; } while (i < end) { bytes.writeByte(UNSAFE.getByte(tObject, i)); ++i; } } public T read(Bytes bytes, T tObject) { long i = metadata.start; long end = metadata.start + metadata.length; while (i < end - 7) { UNSAFE.putLong(tObject, i, bytes.readLong()); i += 8; } while (i < end) { UNSAFE.putByte(tObject, i, bytes.readByte()); ++i; } return tObject; } public long length() { return metadata.length; } }Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/direct/ObjectMarshallers.java000066400000000000000000000054521226752375100330360ustar00rootroot00000000000000package net.openhft.lang.io.serialization.direct; import net.openhft.lang.io.NativeBytes; import java.lang.reflect.Field; import java.util.*; import java.util.logging.Logger; import static java.util.logging.Level.WARNING; import static net.openhft.lang.io.serialization.direct.DirectSerializationMetadata.SerializationMetadata; public final class ObjectMarshallers { private static final Logger Log = Logger.getLogger(ObjectMarshallers.class.getName()); private static final Map metadata = new HashMap(); @SuppressWarnings("unchecked") public static ObjectMarshaller forClass(Class clazz) { ObjectMarshaller om = metadata.get(clazz); if (om == null) { List fields = Introspect.fields(clazz); List eligibleFields = DirectSerializationFilter.stopAtFirstIneligibleField(fields); SerializationMetadata serializationMetadata; if (hasIneligibleFields(fields, eligibleFields)) { WarnAboutIneligibleFields.apply(clazz, fields, eligibleFields); serializationMetadata = DirectSerializationMetadata.extractMetadataForPartialCopy(eligibleFields); } else { serializationMetadata = DirectSerializationMetadata.extractMetadata(eligibleFields); } om = new ObjectMarshaller(serializationMetadata); Log.log(WARNING, String.format("Class %s has metadata %s", clazz.getName(), serializationMetadata)); metadata.put(clazz, om); } return (ObjectMarshaller) om; } private static boolean hasIneligibleFields(List allFields, List eligibleFields) { return allFields.size() != eligibleFields.size(); } private static class WarnAboutIneligibleFields { static void apply(Class clazz, List allFields, List eligibleFields) { List ineligibleFields = allFields.subList(eligibleFields.size(), allFields.size()); Log.log(WARNING, String.format( "The following fields in Class %s will not be copied by ObjectMarshaller:\n%s", clazz.getName(), commaSeparate(ineligibleFields) )); } private static String commaSeparate(Collection fields) { StringBuilder sb = new StringBuilder(); boolean first = true; for (Field field : fields) { if (first) { sb.append("\t"); sb.append(field.getName()); first = false; } else { sb.append("\n\t"); sb.append(field.getName()); } } return sb.toString(); } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/000077500000000000000000000000001226752375100262505ustar00rootroot00000000000000BytesMarshallableMarshaller.java000066400000000000000000000031361226752375100344500ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshallable; import net.openhft.lang.io.serialization.BytesMarshaller; import net.openhft.lang.io.NativeBytes; import org.jetbrains.annotations.NotNull; /** * @author peter.lawrey */ public class BytesMarshallableMarshaller implements BytesMarshaller { @NotNull private final Class classMarshaled; public BytesMarshallableMarshaller(@NotNull Class classMarshaled) { this.classMarshaled = classMarshaled; } @Override public void write(@NotNull Bytes bytes, @NotNull E e) { e.writeMarshallable(bytes); } @Override public E read(@NotNull Bytes bytes) { E e; try { e = (E) NativeBytes.UNSAFE.allocateInstance(classMarshaled); } catch (Exception e2) { throw new IllegalStateException(e2); } e.readMarshallable(bytes); return e; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/ClassMarshaller.java000066400000000000000000000067751226752375100322120ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.Compare; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.CompactBytesMarshaller; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.ref.WeakReference; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; /** * @author peter.lawrey */ public class ClassMarshaller implements CompactBytesMarshaller { private static final int CACHE_SIZE = 1019; private static final Map SC_SHORT_NAME = new LinkedHashMap(); private static final Map CS_SHORT_NAME = new LinkedHashMap(); static { Class[] classes = {Boolean.class, Byte.class, Character.class, Short.class, Integer.class, Long.class, Float.class, Double.class, String.class, Class.class, BigInteger.class, BigDecimal.class, Date.class}; for (Class clazz : classes) { String simpleName = clazz.getSimpleName(); SC_SHORT_NAME.put(simpleName, clazz); CS_SHORT_NAME.put(clazz, simpleName); } } private final ClassLoader classLoader; private final StringBuilder className = new StringBuilder(40); @Nullable @SuppressWarnings("unchecked") private WeakReference[] classWeakReference = null; public ClassMarshaller(ClassLoader classLoader) { this.classLoader = classLoader; } @Override public void write(@NotNull Bytes bytes, @NotNull Class aClass) { String s = CS_SHORT_NAME.get(aClass); if (s == null) s = aClass.getName(); bytes.writeUTFΔ(s); } @Nullable @Override public Class read(@NotNull Bytes bytes) { className.setLength(0); bytes.readUTFΔ(className); return load(className); } @Nullable private Class load(@NotNull CharSequence name) { int hash = (int) (Compare.calcLongHashCode(name) & 0x7ffffff) % CACHE_SIZE; if (classWeakReference == null) //noinspection unchecked classWeakReference = new WeakReference[CACHE_SIZE]; WeakReference ref = classWeakReference[hash]; if (ref != null) { Class clazz = ref.get(); if (clazz != null && clazz.getName().equals(name)) return clazz; } try { Class clazz = SC_SHORT_NAME.get(name.toString()); if (clazz != null) return clazz; clazz = classLoader.loadClass(name.toString()); classWeakReference[hash] = new WeakReference(clazz); return clazz; } catch (ClassNotFoundException e) { throw new IllegalArgumentException(e); } } @Override public byte code() { return 'C' & 31; // control C } } CompactEnumBytesMarshaller.java000066400000000000000000000024071226752375100342740ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.serialization.CompactBytesMarshaller; import org.jetbrains.annotations.NotNull; /** * Created with IntelliJ IDEA. User: peter Date: 09/12/13 Time: 17:05 To change this template use File | Settings | File * Templates. */ public class CompactEnumBytesMarshaller extends GenericEnumMarshaller implements CompactBytesMarshaller { private final byte code; public CompactEnumBytesMarshaller(@NotNull Class classMarshaled, int capacity, byte code) { super(classMarshaled, capacity); this.code = code; } @Override public byte code() { return code; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/DateMarshaller.java000066400000000000000000000053731226752375100320130ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.CompactBytesMarshaller; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Date; /** * @author peter.lawrey */ public class DateMarshaller implements CompactBytesMarshaller { final int size1; private final StringBuilder sb = new StringBuilder(); @Nullable private Date[] interner = null; public DateMarshaller(int size) { int size2 = 128; while (size2 < size && size2 < (1 << 20)) size2 <<= 1; this.size1 = size2 - 1; } private static long parseLong(@NotNull CharSequence sb) { long num = 0; boolean negative = false; for (int i = 0; i < sb.length(); i++) { char b = sb.charAt(i); // if (b >= '0' && b <= '9') if ((b - ('0' + Integer.MIN_VALUE)) <= 9 + Integer.MIN_VALUE) num = num * 10 + b - '0'; else if (b == '-') negative = true; else break; } return negative ? -num : num; } @Override public void write(@NotNull Bytes bytes, @NotNull Date date) { long pos = bytes.position(); bytes.writeUnsignedByte(0); bytes.append(date.getTime()); bytes.writeUnsignedByte(pos, (int) (bytes.position() - 1 - pos)); } @Nullable @Override public Date read(@NotNull Bytes bytes) { bytes.readUTFΔ(sb); long time = parseLong(sb); return lookupDate(time); } @Nullable private Date lookupDate(long time) { int idx = hashFor(time); if (interner == null) interner = new Date[size1 + 1]; Date date = interner[idx]; if (date != null && date.getTime() == time) return date; return interner[idx] = new Date(time); } private int hashFor(long time) { long h = time; h ^= (h >>> 41) ^ (h >>> 20); h ^= (h >>> 14) ^ (h >>> 7); return (int) (h & size1); } @Override public byte code() { return 'T' & 31; // Control T. } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/EnumBytesMarshaller.java000066400000000000000000000056341226752375100330510ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshaller; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.BitSet; import java.util.LinkedHashMap; import java.util.Map; /** * @author peter.lawrey */ public class EnumBytesMarshaller> implements BytesMarshaller { @NotNull private final Class classMarshaled; @SuppressWarnings("unchecked") private final E[] interner = (E[]) new Enum[1024]; private final BitSet internerDup = new BitSet(1024); private final Map map = new LinkedHashMap(); private final E defaultValue; private final int mask; private final StringBuilder reader = new StringBuilder(); public EnumBytesMarshaller(@NotNull Class classMarshaled, E defaultValue) { this.classMarshaled = classMarshaled; this.defaultValue = defaultValue; mask = interner.length - 1; for (E e : classMarshaled.getEnumConstants()) { map.put(e.name(), e); int idx = hashFor(e.name()); if (!internerDup.get(idx)) { if (interner[idx] != null) { //noinspection UnqualifiedFieldAccess,AssignmentToNull interner[idx] = null; internerDup.set(idx); } else { interner[idx] = e; } } } } @Override public void write(@NotNull Bytes bytes, @Nullable E e) { bytes.writeUTFΔ(e == null ? "" : e.name()); } private int hashFor(@NotNull CharSequence cs) { int h = 0; for (int i = 0, length = cs.length(); i < length; i++) h = 57 * h + cs.charAt(i); h ^= (h >>> 20) ^ (h >>> 12); h ^= (h >>> 7) ^ (h >>> 4); return h & mask; } @Override public E read(@NotNull Bytes bytes) { bytes.readUTFΔ(reader); return builderToEnum(); } private E builderToEnum() { int num = hashFor(reader); int idx = num & mask; E e = interner[idx]; if (e != null) return e; if (!internerDup.get(idx)) return defaultValue; e = map.get(reader.toString()); return e == null ? defaultValue : e; } } ExternalizableMarshaller.java000066400000000000000000000032571226752375100340270ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshaller; import net.openhft.lang.io.NativeBytes; import org.jetbrains.annotations.NotNull; import java.io.Externalizable; import java.io.IOException; /** * @author peter.lawrey */ public class ExternalizableMarshaller implements BytesMarshaller { @NotNull private final Class classMarshaled; public ExternalizableMarshaller(@NotNull Class classMarshaled) { this.classMarshaled = classMarshaled; } @Override public void write(Bytes bytes, @NotNull E e) { try { e.writeExternal(bytes); } catch (IOException e2) { throw new IllegalStateException(e2); } } @Override public E read(Bytes bytes) { E e; try { e = (E) NativeBytes.UNSAFE.allocateInstance(classMarshaled); e.readExternal(bytes); } catch (Exception e2) { throw new IllegalStateException(e2); } return e; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/GenericEnumMarshaller.java000066400000000000000000000057601226752375100333370ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshaller; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; /** * @author peter.lawrey */ public class GenericEnumMarshaller implements BytesMarshaller { @NotNull private final Class classMarshaled; @Nullable private final Constructor constructor; @Nullable private final Method valueOf; @NotNull private final Map map; public GenericEnumMarshaller(@NotNull Class classMarshaled, final int capacity) { this.classMarshaled = classMarshaled; Constructor constructor = null; Method valueOf = null; try { valueOf = classMarshaled.getMethod("valueOf", String.class); } catch (NoSuchMethodException e) { try { constructor = classMarshaled.getConstructor(String.class); } catch (NoSuchMethodException e1) { throw new IllegalArgumentException(classMarshaled + " doesn't have a valueOf(String) or a Constructor(String)"); } } this.constructor = constructor; this.valueOf = valueOf; map = new LinkedHashMap(128, 0.7f, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > capacity; } }; } @Override public void write(@NotNull Bytes bytes, @Nullable E e) { bytes.writeUTFΔ(e == null ? null : e.toString()); } @Nullable @Override public E read(@NotNull Bytes bytes) { String s = bytes.readUTFΔ(); return s == null ? null : valueOf(s); } private E valueOf(String s) { E e = map.get(s); if (e == null) try { if (constructor != null) { map.put(s, e = constructor.newInstance(s)); } else { @SuppressWarnings("unchecked") E invoke = (E) valueOf.invoke(null, s); map.put(s, e = invoke); } } catch (Exception t) { throw new AssertionError(t.getCause()); } return e; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoMarshaller.java000066400000000000000000000022561226752375100315070ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshaller; /** * Created with IntelliJ IDEA. User: peter.lawrey Date: 19/09/13 Time: 18:26 To change this template use File | Settings | File * Templates. */ public enum NoMarshaller implements BytesMarshaller { INSTANCE; @Override public void write(Bytes bytes, Void aVoid) { throw new UnsupportedOperationException(); } @Override public Void read(Bytes bytes) { throw new UnsupportedOperationException(); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringMarshaller.java000066400000000000000000000032371226752375100324010ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.CompactBytesMarshaller; import net.openhft.lang.pool.StringInterner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author peter.lawrey */ public class StringMarshaller implements CompactBytesMarshaller { private final int size; private final StringBuilder reader = new StringBuilder(); private StringInterner interner; public StringMarshaller(int size) { this.size = size; } @Override public void write(@NotNull Bytes bytes, String s) { bytes.writeUTFΔ(s); } @Nullable @Override public String read(@NotNull Bytes bytes) { if (bytes.readUTFΔ(reader)) return builderToString(); return null; } private String builderToString() { if (interner == null) interner = new StringInterner(size); return interner.intern(reader); } public byte code() { return 'S' & 31; } } VanillaBytesMarshallerFactory.java000066400000000000000000000070341226752375100350000ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/io/serialization/impl/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization.impl; import net.openhft.lang.io.serialization.BytesMarshallable; import net.openhft.lang.io.serialization.BytesMarshaller; import net.openhft.lang.io.serialization.BytesMarshallerFactory; import net.openhft.lang.io.serialization.CompactBytesMarshaller; import org.jetbrains.annotations.NotNull; import java.io.Externalizable; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; /** * @author peter.lawrey */ public class VanillaBytesMarshallerFactory implements BytesMarshallerFactory { private final Map marshallerMap = new LinkedHashMap(); private final BytesMarshaller[] compactMarshallerMap = new BytesMarshaller[256]; // private final Map marshallerTextMap = new LinkedHashMap(); { BytesMarshaller stringMarshaller = new StringMarshaller(16 * 1024); addMarshaller(String.class, stringMarshaller); addMarshaller(CharSequence.class, stringMarshaller); addMarshaller(Class.class, new ClassMarshaller(Thread.currentThread().getContextClassLoader())); addMarshaller(Date.class, new DateMarshaller(10191)); addMarshaller(Integer.class, new CompactEnumBytesMarshaller(Integer.class, 10191, (byte) ('I' & 31))); addMarshaller(Long.class, new CompactEnumBytesMarshaller(Long.class, 10191, (byte) ('L' & 31))); addMarshaller(Double.class, new CompactEnumBytesMarshaller(Double.class, 10191, (byte) ('D' & 31))); } @NotNull @SuppressWarnings("unchecked") @Override public BytesMarshaller acquireMarshaller(@NotNull Class eClass, boolean create) { BytesMarshaller em = marshallerMap.get(eClass); if (em == null) if (eClass.isEnum()) marshallerMap.put(eClass, em = new EnumBytesMarshaller(eClass, null)); else if (BytesMarshallable.class.isAssignableFrom(eClass)) marshallerMap.put(eClass, em = new BytesMarshallableMarshaller((Class) eClass)); else if (Externalizable.class.isAssignableFrom(eClass)) marshallerMap.put(eClass, em = new ExternalizableMarshaller((Class) eClass)); else { try { marshallerMap.put(eClass, em = new GenericEnumMarshaller(eClass, 1000)); } catch (Exception e) { marshallerMap.put(eClass, em = NoMarshaller.INSTANCE); } } return em; } @Override public BytesMarshaller getMarshaller(byte code) { return compactMarshallerMap[code & 0xFF]; } public void addMarshaller(Class eClass, BytesMarshaller marshaller) { marshallerMap.put(eClass, marshaller); if (marshaller instanceof CompactBytesMarshaller) compactMarshallerMap[((CompactBytesMarshaller) marshaller).code()] = marshaller; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/000077500000000000000000000000001226752375100231235ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/Byteable.java000066400000000000000000000015511226752375100255170ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.io.Bytes; /** * User: peter.lawrey * Date: 07/10/13 * Time: 21:38 */ public interface Byteable { void bytes(Bytes bytes); void bytes(Bytes bytes, long offset); Bytes bytes(); int maxSize(); }Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/ClassModel.java000066400000000000000000000016041226752375100260150ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import java.lang.reflect.Method; import java.util.Map; import java.util.Set; public interface ClassModel { void setMethod(String name, MethodFilter filter, Method method); Set getNames(); Map filterMapFor(String name); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/CodeGenerator.java000066400000000000000000000012351226752375100265100ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; public interface CodeGenerator { } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/Copyable.java000066400000000000000000000015101226752375100255210ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; /** * User: peter.lawrey * Date: 08/10/13 * Time: 07:45 */ public interface Copyable { /** * Copy from this type. * * @param from to copy from */ void copyFrom(T from); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/DataValueGenerator.java000066400000000000000000000624041226752375100275110ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.compiler.CachedCompiler; import net.openhft.lang.Compare; import net.openhft.lang.Maths; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.serialization.BytesMarshallable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; /** * User: peter.lawrey * Date: 06/10/13 * Time: 19:17 */ public class DataValueGenerator { public static final Comparator COMPARATOR = new Comparator() { @Override public int compare(Class o1, Class o2) { return o1.getName().compareTo(o2.getName()); } }; public static final Comparator> COMPARE_BY_HEAP_SIZE = new Comparator>() { @Override public int compare(Map.Entry o1, Map.Entry o2) { // descending int cmp = -Maths.compare(o1.getValue().heapSize(), o2.getValue().heapSize()); return cmp == 0 ? o1.getKey().compareTo(o2.getKey()) : cmp; } }; private static final Logger LOGGER = Logger.getLogger(DataValueGenerator.class.getName()); final CachedCompiler cc = new CachedCompiler(null, null); private final Map heapClassMap = new ConcurrentHashMap(); private final Map nativeClassMap = new ConcurrentHashMap(); private boolean dumpCode = false; private static String bytesType(Class type) { if (type.isPrimitive()) return Character.toUpperCase(type.getName().charAt(0)) + type.getName().substring(1); if (CharSequence.class.isAssignableFrom(type)) return "UTFΔ"; return "Object"; } public T heapInstance(Class tClass) { try { return (T) acquireHeapClass(tClass).newInstance(); } catch (Exception e) { throw new AssertionError(e); } } public Class acquireHeapClass(Class tClass) throws ClassNotFoundException { Class heapClass = heapClassMap.get(tClass); if (heapClass != null) return heapClass; String actual = new DataValueGenerator().generateHeapObject(tClass); if (dumpCode) LOGGER.info(actual); heapClass = cc.loadFromJava(tClass.getClassLoader(), tClass.getName() + "£heap", actual); heapClassMap.put(tClass, heapClass); return heapClass; } public String generateHeapObject(Class tClass) { return generateHeapObject(DataValueModels.acquireModel(tClass)); } public String generateHeapObject(DataValueModel dvmodel) { SortedSet imported = new TreeSet(COMPARATOR); imported.add(BytesMarshallable.class); imported.add(Bytes.class); imported.add(IOException.class); imported.add(Copyable.class); imported.add(dvmodel.type()); StringBuilder fieldDeclarations = new StringBuilder(); StringBuilder getterSetters = new StringBuilder(); StringBuilder writeMarshal = new StringBuilder(); StringBuilder readMarshal = new StringBuilder(); StringBuilder copy = new StringBuilder(); Map fieldMap = dvmodel.fieldMap(); Map.Entry[] entries = fieldMap.entrySet().toArray(new Map.Entry[fieldMap.size()]); Arrays.sort(entries, COMPARE_BY_HEAP_SIZE); for (Map.Entry entry : entries) { String name = entry.getKey(); FieldModel model = entry.getValue(); Class type = model.type(); if (!type.isPrimitive() && !type.getPackage().getName().equals("java.lang")) imported.add(type); fieldDeclarations.append(" private ").append(type.getName()).append(" _").append(name).append(";\n"); final Method setter = model.setter(); final Method getter = model.getter(); if (setter == null) { copy.append(" ((Copyable) ").append(getter.getName()).append("()).copyFrom(from.").append(getter.getName()).append("());\n"); } else { copy.append(" ").append(setter.getName()).append("(from.").append(getter.getName()).append("());\n"); Class setterType = setter.getParameterTypes()[0]; getterSetters.append(" public void ").append(setter.getName()).append('(').append(setterType.getName()).append(" _) {\n"); if (type == String.class && setterType != String.class) getterSetters.append(" _").append(name).append(" = _.toString();\n"); else getterSetters.append(" _").append(name).append(" = _;\n"); getterSetters.append(" }\n\n"); } getterSetters.append(" public ").append(type.getName()).append(' ').append(getter.getName()).append("() {\n"); getterSetters.append(" return _").append(name).append(";\n"); getterSetters.append(" }\n\n"); Method adder = model.adder(); if (adder != null) { getterSetters.append(" public ").append(type.getName()).append(' ').append(adder.getName()) .append("(").append(adder.getParameterTypes()[0].getName()).append(" _) {\n") .append(" return _").append(name).append(" += _;\n") .append(" }"); } Method atomicAdder = model.atomicAdder(); if (atomicAdder != null) { getterSetters.append(" public synchronized ").append(type.getName()).append(' ').append(atomicAdder.getName()) .append("(").append(adder.getParameterTypes()[0].getName()).append(" _) {\n") .append(" return _").append(name).append(" += _;\n") .append(" }"); } Method cas = model.cas(); if (cas != null) { getterSetters.append(" public synchronized boolean ").append(cas.getName()).append("(") .append(type.getName()).append(" _1, ") .append(type.getName()).append(" _2) {\n") .append(" if (_").append(name).append(" == _1) {\n") .append(" _").append(name).append(" = _2;\n") .append(" return true;\n") .append(" }\n") .append(" return false;\n") .append(" }\n"); } Method tryLockNanos = model.tryLockNanos(); if (tryLockNanos != null) { getterSetters.append(" public boolean ").append(tryLockNanos.getName()).append("(long nanos) {\n") .append(" throw new UnsupportedOperationException();\n") .append(" }"); } Method tryLock = model.tryLock(); if (tryLock != null) { getterSetters.append(" public boolean ").append(tryLock.getName()).append("() {\n") .append(" throw new UnsupportedOperationException();\n") .append(" }"); } Method unlock = model.unlock(); if (unlock != null) { getterSetters.append(" public void ").append(unlock.getName()).append("() {\n") .append(" throw new UnsupportedOperationException();\n") .append(" }"); } Method busyLock = model.busyLock(); if (busyLock != null) { getterSetters.append(" public void ").append(busyLock.getName()).append("() {\n") .append(" throw new UnsupportedOperationException();\n") .append(" }"); } writeMarshal.append(" out.write").append(bytesType(type)).append("(_").append(name).append(");\n"); readMarshal.append(" _").append(name).append(" = in.read").append(bytesType(type)).append("("); if ("Object".equals(bytesType(type))) readMarshal.append(type.getName()).append(".class"); readMarshal.append(");\n"); } StringBuilder sb = new StringBuilder(); sb.append("package ").append(dvmodel.type().getPackage().getName()).append(";\n\n"); sb.append("import static ").append(Compare.class.getName()).append(".*;\n"); for (Class aClass : imported) { sb.append("import ").append(aClass.getName()).append(";\n"); } sb.append("\npublic class ").append(dvmodel.type().getSimpleName()) .append("£heap implements ").append(dvmodel.type().getSimpleName()) .append(", BytesMarshallable, Copyable<").append(dvmodel.type().getName()).append("> {\n"); sb.append(fieldDeclarations).append('\n'); sb.append(getterSetters); sb.append(" @SuppressWarnings(\"unchecked\")\n" + " public void copyFrom(").append(dvmodel.type().getName()).append(" from) {\n"); sb.append(copy); sb.append(" }\n\n"); sb.append(" public void writeMarshallable(Bytes out) {\n"); sb.append(writeMarshal); sb.append(" }\n"); sb.append(" public void readMarshallable(Bytes in) {\n"); sb.append(readMarshal); sb.append(" }\n"); if (Byteable.class.isAssignableFrom(dvmodel.type())) { sb.append(" public void bytes(Bytes bytes) {\n"); sb.append(" throw new UnsupportedOperationException();\n"); sb.append(" }\n"); sb.append(" public void bytes(Bytes bytes, long l) {\n"); sb.append(" throw new UnsupportedOperationException();\n"); sb.append(" }\n"); sb.append(" public Bytes bytes() {\n"); sb.append(" return null;\n"); sb.append(" }\n"); sb.append(" public int maxSize() {\n"); sb.append(" throw new UnsupportedOperationException();\n"); sb.append(" }\n"); } generateObjectMethods(sb, dvmodel, entries); sb.append("}\n"); // System.out.println(sb); return sb.toString(); } private static void generateObjectMethods(StringBuilder sb, DataValueModel dvmodel, Map.Entry[] entries) { int count = 0; StringBuilder hashCode = new StringBuilder(); StringBuilder equals = new StringBuilder(); StringBuilder toString = new StringBuilder(); for (Map.Entry entry : entries) { String name = entry.getKey(); FieldModel model = entry.getValue(); Class type = model.type(); if (count > 0) hashCode.append(") * 10191 +\n "); String getterName = model.getter().getName(); hashCode.append("calcLongHashCode(").append(getterName).append("())"); equals.append(" if(!isEqual(").append(getterName).append("(), that.").append(getterName).append("())) return false;\n"); toString.append(" \", ").append(name).append("= \" + ").append(getterName).append("() +\n"); count++; } sb.append(" public int hashCode() {\n" + " long lhc = longHashCode();\n" + " return (int) ((lhc >>> 32) ^ lhc);\n" + " }\n" + "\n" + " public long longHashCode() {\n" + " return "); for (int i = 1; i < count; i++) sb.append('('); sb.append(hashCode); String simpleName = dvmodel.type().getSimpleName(); sb.append(";\n") .append(" }\n") .append("\n") .append(" public boolean equals(Object o) {\n") .append(" if (this == o) return true;\n") .append(" if (!(o instanceof ").append(simpleName).append(")) return false;\n") .append(" ").append(simpleName).append(" that = (").append(simpleName).append(") o;\n") .append("\n") .append(equals) .append(" return true;\n" + " }\n" + "\n" + " public String toString() {\n" + " return \"").append(simpleName).append(" {\" +\n") .append(toString.substring(0, toString.length() - 3)).append(";\n") .append(" }"); } public T nativeInstance(Class tClass) { try { return (T) acquireNativeClass(tClass).newInstance(); } catch (Exception e) { throw new AssertionError(e); } } public Class acquireNativeClass(Class tClass) throws ClassNotFoundException { Class nativeClass = nativeClassMap.get(tClass); if (nativeClass != null) return nativeClass; DataValueModel dvmodel = DataValueModels.acquireModel(tClass); for (Class clazz : dvmodel.nestedModels()) { Class clazz2 = acquireNativeClass(clazz); } String actual = new DataValueGenerator().generateNativeObject(dvmodel); if (dumpCode) LOGGER.info(actual); nativeClass = cc.loadFromJava(tClass.getClassLoader(), tClass.getName() + "£native", actual); nativeClassMap.put(tClass, nativeClass); return nativeClass; } public String generateNativeObject(Class tClass) { return generateNativeObject(DataValueModels.acquireModel(tClass)); } public String generateNativeObject(DataValueModel dvmodel) { SortedSet imported = new TreeSet(COMPARATOR); imported.add(BytesMarshallable.class); imported.add(ObjectOutput.class); imported.add(ObjectInput.class); imported.add(IOException.class); imported.add(Copyable.class); imported.add(Byteable.class); imported.add(Bytes.class); StringBuilder staticFieldDeclarations = new StringBuilder(); StringBuilder fieldDeclarations = new StringBuilder(); StringBuilder getterSetters = new StringBuilder(); StringBuilder writeMarshal = new StringBuilder(); StringBuilder readMarshal = new StringBuilder(); StringBuilder copy = new StringBuilder(); StringBuilder nestedBytes = new StringBuilder(); Map fieldMap = dvmodel.fieldMap(); Map.Entry[] entries = fieldMap.entrySet().toArray(new Map.Entry[fieldMap.size()]); Arrays.sort(entries, COMPARE_BY_HEAP_SIZE); int offset = 0; for (Map.Entry entry : entries) { String name = entry.getKey(); FieldModel model = entry.getValue(); Class type = model.type(); if (!type.isPrimitive() && !type.getPackage().getName().equals("java.lang")) imported.add(type); String NAME = "_offset + " + name.toUpperCase(); final Method setter = model.setter(); final Method getter = model.getter(); if (dvmodel.isScalar(type)) { staticFieldDeclarations.append(" private static final int ").append(name.toUpperCase()).append(" = ").append(offset).append(";\n"); copy.append(" ").append(setter.getName()).append("(from.").append(getter.getName()).append("());\n"); Class setterType = setter.getParameterTypes()[0]; getterSetters.append(" public void ").append(setter.getName()).append('(').append(setterType.getName()).append(" _) {\n"); getterSetters.append(" _bytes.write").append(bytesType(type)).append("(").append(NAME).append(", "); if (CharSequence.class.isAssignableFrom(type)) getterSetters.append(model.size().value()).append(", "); getterSetters.append("_);\n"); getterSetters.append(" }\n\n"); getterSetters.append(" public ").append(type.getName()).append(' ').append(getter.getName()).append("() {\n"); getterSetters.append(" return _bytes.read").append(bytesType(type)).append("(").append(NAME).append(");\n"); getterSetters.append(" }\n\n"); Method adder = model.adder(); if (adder != null) { getterSetters.append(" public ").append(type.getName()).append(' ').append(adder.getName()) .append("(").append(adder.getParameterTypes()[0].getName()).append(" _) {\n") .append(" return _bytes.add").append(bytesType(type)).append("(").append(NAME).append(", _);\n") .append(" }"); } Method atomicAdder = model.atomicAdder(); if (atomicAdder != null) { getterSetters.append(" public ").append(type.getName()).append(' ').append(atomicAdder.getName()) .append("(").append(adder.getParameterTypes()[0].getName()).append(" _) {\n") .append(" return _bytes.addAtomic").append(bytesType(type)).append("(").append(NAME).append(", _);\n") .append(" }"); } Method cas = model.cas(); if (cas != null) { getterSetters.append(" public boolean ").append(cas.getName()).append("(") .append(type.getName()).append(" _1, ") .append(type.getName()).append(" _2) {\n") .append(" return _bytes.compareAndSwap").append(bytesType(type)).append('(').append(NAME).append(", _1, _2);\n") .append(" }"); } Method tryLockNanos = model.tryLockNanos(); if (tryLockNanos != null) { getterSetters.append(" public boolean ").append(tryLockNanos.getName()).append("(long nanos) {\n") .append(" return _bytes.tryLockNanos").append(bytesType(type)).append('(').append(NAME).append(", nanos);\n") .append(" }"); } Method tryLock = model.tryLock(); if (tryLock != null) { getterSetters.append(" public boolean ").append(tryLock.getName()).append("() {\n") .append(" return _bytes.tryLock").append(bytesType(type)).append('(').append(NAME).append(");\n") .append(" }"); } Method unlock = model.unlock(); if (unlock != null) { getterSetters.append(" public void ").append(unlock.getName()).append("() {\n") .append(" _bytes.unlock").append(bytesType(type)).append('(').append(NAME).append(");\n") .append(" }"); } Method busyLock = model.busyLock(); if (busyLock != null) { getterSetters.append(" public void ").append(busyLock.getName()).append("() throws InterruptedException {\n") .append(" _bytes.busyLock").append(bytesType(type)).append('(').append(NAME).append(");\n") .append(" }"); } writeMarshal.append(" out.write").append(bytesType(type)).append("(") .append(getter.getName()).append("());\n"); readMarshal.append(" ").append(setter.getName()).append("(in.read").append(bytesType(type)).append("());\n"); offset += (model.nativeSize() + 7) >> 3; } else { staticFieldDeclarations.append(" private static final int ").append(name.toUpperCase()).append(" = ").append(offset).append(";\n"); fieldDeclarations.append(" private final ").append(type.getName()).append("£native _").append(name).append(" = new ").append(type.getName()).append("£native();\n"); if (setter == null) { copy.append(" _").append(name).append(".copyFrom(from.").append(getter.getName()).append("());\n"); } else { copy.append(" ").append(setter.getName()).append("(from.").append(getter.getName()).append("());\n"); Class setterType = setter.getParameterTypes()[0]; getterSetters.append(" public void ").append(setter.getName()).append('(').append(setterType.getName()).append(" _) {\n"); if (type == String.class && setterType != String.class) getterSetters.append(" _").append(name).append(" = _.toString();\n"); else getterSetters.append(" _").append(name).append(".copyFrom(_);\n"); getterSetters.append(" }\n\n"); } getterSetters.append(" public ").append(type.getName()).append(' ').append(getter.getName()).append("() {\n"); getterSetters.append(" return _").append(name).append(";\n"); getterSetters.append(" }\n\n"); writeMarshal.append(" _").append(name).append(".writeMarshallable(out);\n"); readMarshal.append(" _").append(name).append(".readMarshallable(in);\n"); nestedBytes.append(" ((Byteable) _").append(name).append(").bytes(bytes, ").append(NAME).append(");\n"); DataValueModel dvmodel2 = dvmodel.nestedModel(type); Map fieldMap2 = dvmodel2.fieldMap(); Map.Entry[] entries2 = fieldMap2.entrySet().toArray(new Map.Entry[fieldMap2.size()]); Arrays.sort(entries2, COMPARE_BY_HEAP_SIZE); for (Map.Entry entry2 : entries2) { FieldModel model2 = entry2.getValue(); offset += (model2.nativeSize() + 7) >> 3; } } } fieldDeclarations.append("\n") .append(" private Bytes _bytes;\n") .append(" private long _offset;\n"); StringBuilder sb = new StringBuilder(); sb.append("package ").append(dvmodel.type().getPackage().getName()).append(";\n\n"); sb.append("import static ").append(Compare.class.getName()).append(".*;\n"); for (Class aClass : imported) { sb.append("import ").append(aClass.getName()).append(";\n"); } sb.append("\npublic class ").append(dvmodel.type().getSimpleName()) .append("£native implements ").append(dvmodel.type().getSimpleName()) .append(", BytesMarshallable, Byteable, Copyable<").append(dvmodel.type().getName()).append("> {\n"); sb.append(staticFieldDeclarations).append('\n'); sb.append(fieldDeclarations).append('\n'); sb.append(getterSetters); sb.append(" public void copyFrom(").append(dvmodel.type().getName()).append(" from) {\n"); sb.append(copy); sb.append(" }\n\n"); sb.append(" public void writeMarshallable(Bytes out) {\n"); sb.append(writeMarshal); sb.append(" }\n"); sb.append(" public void readMarshallable(Bytes in) {\n"); sb.append(readMarshal); sb.append(" }\n"); sb.append(" public void bytes(Bytes bytes) {\n"); sb.append(" bytes(bytes, 0L);\n"); sb.append(" }\n"); sb.append(" public void bytes(Bytes bytes, long offset) {\n"); sb.append(" this._bytes = bytes;\n"); sb.append(" this._offset = offset;\n"); sb.append(nestedBytes); sb.append(" }\n"); sb.append(" public Bytes bytes() {\n"); sb.append(" return _bytes;\n"); sb.append(" }\n"); sb.append(" public int maxSize() {\n"); sb.append(" return ").append(offset).append(";\n"); sb.append(" }\n"); generateObjectMethods(sb, dvmodel, entries); sb.append("}\n"); // System.out.println(sb); return sb.toString(); } public boolean isDumpCode() { return dumpCode; } public void setDumpCode(boolean dumpCode) { this.dumpCode = dumpCode; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/DataValueMetaModel.java000066400000000000000000000034721226752375100274320ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.io.serialization.BytesMarshallable; import java.io.Externalizable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class DataValueMetaModel { private final Set ignoredClasses = new HashSet(); private final List filters = new ArrayList(); public DataValueMetaModel() { addIgnoredClass(Object.class); addIgnoredClass(Externalizable.class); addIgnoredClass(Copyable.class); addIgnoredClass(Byteable.class); addIgnoredClass(BytesMarshallable.class); for (VanillaFilter vanillaFilter : VanillaFilter.values()) { addMethodFilter(vanillaFilter); } } public void addIgnoredClass(Class aClass) { ignoredClasses.add(aClass); } public void addMethodFilter(MethodFilter filter) { int pos = insertionPoint(filter); filters.add(pos, filter); } private int insertionPoint(MethodFilter filter) { for (int i = 0; i < filters.size(); i++) if (filters.get(i).matches() < filter.matches()) return i; return filters.size(); } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/DataValueModel.java000066400000000000000000000017251226752375100266220ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import java.util.Map; import java.util.Set; /** * User: peter.lawrey * Date: 06/10/13 * Time: 17:06 */ public interface DataValueModel { Map fieldMap(); boolean isScalar(Class nClass); Set nestedModels(); DataValueModel nestedModel(Class nClass); Class type(); }Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/DataValueModelImpl.java000066400000000000000000000375261226752375100274540ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.io.serialization.BytesMarshallable; import net.openhft.lang.model.constraints.Digits; import net.openhft.lang.model.constraints.MaxSize; import net.openhft.lang.model.constraints.Range; import java.io.Externalizable; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * User: peter.lawrey * Date: 06/10/13 * Time: 17:23 */ public class DataValueModelImpl implements DataValueModel { static final Map HEAP_SIZE_MAP = new HashMap(); static { HEAP_SIZE_MAP.put(boolean.class, 1); HEAP_SIZE_MAP.put(byte.class, 8); HEAP_SIZE_MAP.put(char.class, 16); HEAP_SIZE_MAP.put(short.class, 16); HEAP_SIZE_MAP.put(int.class, 32); HEAP_SIZE_MAP.put(float.class, 32); HEAP_SIZE_MAP.put(long.class, 64); HEAP_SIZE_MAP.put(double.class, 64); } private final Map fieldModelMap = new TreeMap(); private final Class type; private final Map nestedMap = new HashMap(); public DataValueModelImpl(Class type) { this.type = type; if (!type.isInterface()) throw new IllegalArgumentException("type must be an interface, was " + type); Method[] methods = type.getMethods(); for (Method method : methods) { Class declaringClass = method.getDeclaringClass(); if (declaringClass == Object.class || declaringClass == Externalizable.class || declaringClass == BytesMarshallable.class || declaringClass == Copyable.class || declaringClass == Byteable.class) continue; String name = method.getName(); Class[] parameterTypes = method.getParameterTypes(); final Class returnType = method.getReturnType(); switch (parameterTypes.length) { case 0: { String name5 = getUnlock(name); if (name5 != null && returnType == void.class) { FieldModelImpl fm = acquireField(name5); fm.unlock(method); break; } String name4 = getBusyLock(name); if (name4 != null && returnType == void.class) { FieldModelImpl fm = acquireField(name4); fm.busyLock(method); break; } String name3 = getTryLock(name); if (name3 != null && returnType == boolean.class) { FieldModelImpl fm = acquireField(name3); fm.tryLock(method); break; } if (returnType == void.class) throw new IllegalArgumentException("void () not supported " + method); String name2 = getGetter(name, returnType); FieldModelImpl fm = acquireField(name2); fm.getter(method); break; } case 1: { String name5 = getTryLockNanos(name); if (name5 != null && returnType == boolean.class) { FieldModelImpl fm = acquireField(name5); fm.tryLockNanos(method); break; } String name4 = getAtomicAdder(name); if (name4 != null) { FieldModelImpl fm = acquireField(name4); fm.atomicAdder(method); break; } String name3 = getAdder(name); if (name3 != null) { FieldModelImpl fm = acquireField(name3); fm.adder(method); break; } String name6 = getGetter(name, returnType); if (name6 != null && parameterTypes[0] == int.class && returnType != void.class) { FieldModelImpl fm = acquireField(name6); fm.indexedGetter(method); break; } if (returnType != void.class) throw new IllegalArgumentException("setter must be void " + method); String name2 = getSetter(name); FieldModelImpl fm = acquireField(name2); fm.setter(method); break; } case 2: { String name2 = getCAS(name); if (name2 != null && returnType == boolean.class) { FieldModelImpl fm = acquireField(name2); fm.cas(method); break; } String name3 = getSetter(name); if (name3 != null && parameterTypes[0] == int.class && returnType == void.class) { FieldModelImpl fm = acquireField(name3); fm.indexedSetter(method); break; } } default: { throw new IllegalArgumentException("method not supported " + method); } } } for (Map.Entry entry : fieldModelMap.entrySet()) { FieldModelImpl model = entry.getValue(); if (model.getter() == null || (model.setter() == null && model.getter().getReturnType().isPrimitive())) if (model.indexedGetter() == null || (model.indexedSetter() == null && model.indexedGetter().getReturnType().isPrimitive())) throw new IllegalArgumentException("Field " + entry.getKey() + " must have a getter and setter."); Class ftype = model.type(); if (!isScalar(ftype) && !nestedMap.containsKey(ftype)) nestedMap.put(ftype, new DataValueModelImpl(ftype)); } } private static String getCAS(String name) { final int len = 14; if (name.length() > len && name.startsWith("compareAndSwap") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private static String getAtomicAdder(String name) { final int len = 9; if (name.length() > len && name.startsWith("addAtomic") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private static String getAdder(String name) { final int len = 3; if (name.length() > len && name.startsWith("add") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private static String getSetter(String name) { final int len = 3; if (name.length() > len && name.startsWith("set") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return name; } private static String getGetter(String name, Class returnType) { if (name.length() > 3 && name.startsWith("get") && Character.isUpperCase(name.charAt(3))) return Character.toLowerCase(name.charAt(3)) + name.substring(4); if ((returnType == boolean.class || returnType == Boolean.class) && name.length() > 2 && name.startsWith("is") && Character.isUpperCase(name.charAt(2))) return Character.toLowerCase(name.charAt(2)) + name.substring(3); return name; } private String getBusyLock(String name) { final int len = 8; if (name.length() > len && name.startsWith("busyLock") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private String getUnlock(String name) { final int len = 6; if (name.length() > len && name.startsWith("unlock") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private String getTryLockNanos(String name) { final int len = 12; if (name.length() > len && name.startsWith("tryLockNanos") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private String getTryLock(String name) { final int len = 7; if (name.length() > len && name.startsWith("tryLock") && Character.isUpperCase(name.charAt(len))) return Character.toLowerCase(name.charAt(len)) + name.substring(len + 1); return null; } private FieldModelImpl acquireField(String name) { FieldModelImpl fieldModelImpl = fieldModelMap.get(name); if (fieldModelImpl == null) fieldModelMap.put(name, fieldModelImpl = new FieldModelImpl(name)); return fieldModelImpl; } @Override public Map fieldMap() { return fieldModelMap; } public boolean isScalar(Class type) { return type.isPrimitive() || CharSequence.class.isAssignableFrom(type); } @Override public Set nestedModels() { return nestedMap.keySet(); } @Override public DataValueModel nestedModel(Class nClass) { @SuppressWarnings("unchecked") DataValueModel model = (DataValueModel) (nClass == type ? this : nestedMap.get(nClass)); return model; } @Override public Class type() { return type; } static class FieldModelImpl implements FieldModel { private final String name; private Method getter, setter; private Digits digits; private Range range; private MaxSize maxSize; private MaxSize indexSize; private Method adder; private Method atomicAdder; private Method cas; private Method tryLockNanos; private Method tryLock; private Method busyLock; private Method unlock; private Method indexedGetter; private Method indexedSetter; public FieldModelImpl(String name) { this.name = name; } public String name() { return name; } public void getter(Method getter) { this.getter = getter; } public Method getter() { return getter; } public void setter(Method setter) { this.setter = setter; for (Annotation a : setter.getParameterAnnotations()[0]) { if (a instanceof Digits) digits = (Digits) a; if (a instanceof Range) range = (Range) a; if (a instanceof MaxSize) maxSize = (MaxSize) a; } } public Method setter() { return setter; } @Override public Class type() { return (Class) (getter != null ? getter.getReturnType() : indexedGetter != null ? indexedGetter.getReturnType() : null); } public void adder(Method method) { adder = method; } public Method adder() { return adder; } @Override public int heapSize() { Integer size = HEAP_SIZE_MAP.get(type()); if (size == null) return -1; return size; } // maxSize in bits. @Override public int nativeSize() { Integer size = HEAP_SIZE_MAP.get(type()); if (size != null) return size; MaxSize maxSize2 = size(); if (maxSize2 == null) throw new AssertionError(type() + " without a @MaxSize not supported for native types"); return maxSize2.value() << 3; } @Override public Digits digits() { return digits; } @Override public Range range() { return range; } @Override public MaxSize size() { return maxSize; } @Override public String toString() { return "FieldModel{" + "name='" + name + '\'' + ", getter=" + (indexedGetter != null ? indexedGetter : getter) + ", setter=" + (indexedSetter != null ? indexedSetter : setter) + (digits == null ? "" : ", digits= " + digits) + (range == null ? "" : ", range= " + range) + (maxSize == null ? "" : ", size= " + maxSize) + ((indexedGetter == null && indexedSetter == null) ? "" : ", indexSize= " + indexSize) + '}'; } public void atomicAdder(Method method) { atomicAdder = method; } public Method atomicAdder() { return atomicAdder; } public void cas(Method method) { cas = method; } public Method cas() { return cas; } public void tryLockNanos(Method method) { tryLockNanos = method; } public Method tryLockNanos() { return tryLockNanos; } public void tryLock(Method tryLock) { this.tryLock = tryLock; } public Method tryLock() { return tryLock; } public void busyLock(Method busyLock) { this.busyLock = busyLock; } public Method busyLock() { return busyLock; } public void unlock(Method unlock) { this.unlock = unlock; } public Method unlock() { return unlock; } public void indexSize(MaxSize indexSize) { if (indexSize != null) this.indexSize = indexSize; } public MaxSize indexSize() { return indexSize; } public void indexedGetter(Method indexedGetter) { this.indexedGetter = indexedGetter; indexAnnotations(indexedGetter); } public Method indexedGetter() { return indexedGetter; } public void indexedSetter(Method indexedSetter) { this.indexedSetter = indexedSetter; indexAnnotations(indexedSetter); } public void indexAnnotations(Method method) { for (Annotation a : method.getParameterAnnotations()[0]) { // if (a instanceof Digits) // digits = (Digits) a; // if (a instanceof Range) // range = (Range) a; if (a instanceof MaxSize) indexSize = (MaxSize) a; } } public Method indexedSetter() { return indexedSetter; } } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/DataValueModels.java000066400000000000000000000026421226752375100270040ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import java.util.Map; import java.util.WeakHashMap; /** * User: peter.lawrey * Date: 06/10/13 * Time: 17:14 */ public enum DataValueModels { ; private static final Map MODEL_MAP = new WeakHashMap(); public static synchronized DataValueModel getModel(Class tClass) { return MODEL_MAP.get(tClass); } public static synchronized void putModel(Class tClass, DataValueModel model) { MODEL_MAP.put(tClass, model); } public static DataValueModel acquireModel(Class tClass) { DataValueModel model = getModel(tClass); if (model == null) { model = new DataValueModelImpl(tClass); putModel(tClass, model); } return model; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/FieldModel.java000066400000000000000000000023711226752375100257750ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.model.constraints.Digits; import net.openhft.lang.model.constraints.MaxSize; import net.openhft.lang.model.constraints.Range; import java.lang.reflect.Method; /** * User: peter.lawrey * Date: 06/10/13 * Time: 18:22 */ public interface FieldModel { String name(); Method getter(); Method setter(); Method adder(); Method atomicAdder(); Method cas(); Method tryLockNanos(); Method tryLock(); Method busyLock(); Method unlock(); Class type(); int heapSize(); int nativeSize(); Digits digits(); Range range(); MaxSize size(); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/HeapCodeGenerator.java000066400000000000000000000126151226752375100273120ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; public enum HeapCodeGenerator implements CodeGenerator { /* GET_VALUE { public void addCode(CodeModel codeModel, Method method) { StringBuilder sb = codeModel.acquireMethod() } }, SET_VALUE { @Override public int matches() { return 3; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1 || method.getReturnType() == void.class) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("set") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, ADD_VALUE { @Override public int matches() { return 3; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("add") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, ADD_ATOMIC_VALUE { @Override public int matches() { return 8; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("addAtomic") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, COMPARE_AND_SWAP_VALUE { @Override public int matches() { return 15; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("compareAndSwap") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, TRY_LOCK_VALUE { @Override public int matches() { return 7; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("tryLock") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, TRY_LOCK_NANOS_VALUE { @Override public int matches() { return 12; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("tryLockNanos") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, BUSY_LOCK_VALUE { @Override public int matches() { return 8; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("busyLock") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, UNLOCK_VALUE { @Override public int matches() { return 6; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("unlock") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } },*/ } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/MethodFilter.java000066400000000000000000000014201226752375100263510ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import java.lang.reflect.Method; public interface MethodFilter { int matches(); String nameFor(Method method, Class[] parameterTypes); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/MethodTemplate.java000066400000000000000000000013711226752375100267040ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import java.lang.reflect.Method; public interface MethodTemplate { void generate(Method method, ClassModel classModel); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/VanillaFilter.java000066400000000000000000000135461226752375100265330ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import java.lang.reflect.Method; public enum VanillaFilter implements MethodFilter { GET_VALUE { @Override public int matches() { return 3; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 0 || method.getReturnType() != void.class) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("get") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, SET_VALUE { @Override public int matches() { return 3; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1 || method.getReturnType() == void.class) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("set") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, ADD_VALUE { @Override public int matches() { return 3; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("add") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, ADD_ATOMIC_VALUE { @Override public int matches() { return 8; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("addAtomic") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, COMPARE_AND_SWAP_VALUE { @Override public int matches() { return 15; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("compareAndSwap") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, TRY_LOCK_VALUE { @Override public int matches() { return 7; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("tryLock") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, TRY_LOCK_NANOS_VALUE { @Override public int matches() { return 12; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("tryLockNanos") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, BUSY_LOCK_VALUE { @Override public int matches() { return 8; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("busyLock") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, UNLOCK_VALUE { @Override public int matches() { return 6; } @Override public String nameFor(Method method, Class[] parameterTypes) { if (parameterTypes.length != 1) return null; final String name = method.getName(); final int pos = matches(); if (name.startsWith("unlock") && Character.isUpperCase(name.charAt(pos))) return Character.toLowerCase(name.charAt(pos)) + name.substring(pos + 1); return null; } }, } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/constraints/000077500000000000000000000000001226752375100254725ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/constraints/Digits.java000066400000000000000000000021221226752375100275550ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model.constraints; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * The maximum size in encoded bytes for a variable length data type. */ @Target(PARAMETER) @Retention(RUNTIME) @Documented public @interface Digits { int integer() default 12; int decimal() default 6; } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/constraints/MaxSize.java000066400000000000000000000021341226752375100277150ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model.constraints; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * The maximum size in encoded bytes for a variable length data type. The units is either elements, or bytes. */ @Target(PARAMETER) @Retention(RUNTIME) @Documented public @interface MaxSize { int value() default 64; } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/model/constraints/Range.java000066400000000000000000000021131226752375100273660ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model.constraints; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * The lowest to highest values allowed (inclusive) */ @Target(PARAMETER) @Retention(RUNTIME) @Documented public @interface Range { long min() default Long.MIN_VALUE; long max() default Long.MAX_VALUE; } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/pool/000077500000000000000000000000001226752375100227745ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/pool/StringInterner.java000077500000000000000000000046571226752375100266330ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.pool; import net.openhft.lang.Maths; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author peter.lawrey */ public class StringInterner { @NotNull private final String[] interner; private final int mask; public StringInterner(int capacity) { int n = Maths.nextPower2(capacity, 128); interner = new String[n]; mask = n - 1; } private static boolean isEqual(@Nullable CharSequence s, @NotNull CharSequence cs) { if (s == null) return false; if (s.length() != cs.length()) return false; for (int i = 0; i < cs.length(); i++) if (s.charAt(i) != cs.charAt(i)) return false; return true; } /* private static boolean isEqual(@Nullable CharSequence s, @NotNull byte[] bytes, int off, int len) { if (s == null) return false; if (s.length() != len) return false; for (int i = 0; i < len; i++) if (s.charAt(i) != (bytes[off + i] & 0xFF)) return false; return true; } @NotNull public String intern(@NotNull byte[] bytes, int off, int len) { long hash = NativeBytes.longHash(bytes, off, len); int h = Maths.hash(hash) & mask; String s = interner[h]; if (isEqual(s, bytes, off, len)) return s; String s2 = new String(bytes, off, len, IOTools.ISO_8859_1); return interner[h] = s2; }*/ @NotNull public String intern(@NotNull CharSequence cs) { long hash = 0; for (int i = 0; i < cs.length(); i++) hash = 57 * hash + cs.charAt(i); int h = Maths.hash(hash) & mask; String s = interner[h]; if (isEqual(s, cs)) return s; String s2 = cs.toString(); return interner[h] = s2; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/testing/000077500000000000000000000000001226752375100235005ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/testing/Differencer.java000066400000000000000000000014131226752375100265560ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.testing; /** * User: peter.lawrey * Date: 05/08/13 * Time: 19:06 */ public interface Differencer { long sample(long startTime, long endTime); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/testing/RunningMinimum.java000066400000000000000000000031521226752375100273200ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.testing; /** * User: peter.lawrey * Date: 05/08/13 * Time: 19:06 */ public class RunningMinimum implements Differencer { private final long actualMinimum; private final int drift; private long lastStartTime = Long.MIN_VALUE; private long minimum = Long.MAX_VALUE; public RunningMinimum(long actualMinimum) { this(actualMinimum, 100 * 1000); } public RunningMinimum(long actualMinimum, int drift) { this.actualMinimum = actualMinimum; this.drift = drift; } @Override public long sample(long startTime, long endTime) { if (lastStartTime + drift <= startTime) { if (lastStartTime != Long.MIN_VALUE) minimum += (startTime - lastStartTime) / drift; lastStartTime = startTime; } long delta = endTime - startTime; if (minimum > delta) minimum = delta; return delta - minimum + actualMinimum; } public long minimum() { return minimum; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/testing/VanillaDifferencer.java000066400000000000000000000015451226752375100300730ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.testing; /** * User: peter.lawrey * Date: 05/08/13 * Time: 19:07 */ public class VanillaDifferencer implements Differencer { @Override public long sample(long startTime, long endTime) { return endTime - startTime; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/thread/000077500000000000000000000000001226752375100232725ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/thread/NamedThreadFactory.java000066400000000000000000000030051226752375100276370ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.thread; import org.jetbrains.annotations.NotNull; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; /** * User: peter.lawrey Date: 18/08/13 Time: 11:37 */ public class NamedThreadFactory implements ThreadFactory { private final AtomicInteger id = new AtomicInteger(); private final String name; private final Boolean daemon; public NamedThreadFactory(@NotNull String name) { this(name, null); } public NamedThreadFactory(@NotNull String name, Boolean daemon) { this.name = name; this.daemon = daemon; } @NotNull @Override public Thread newThread(@NotNull Runnable r) { int id = this.id.getAndIncrement(); String nameN = id == 0 ? name : (name + '-' + id); Thread t = new Thread(r, nameN); if (daemon != null) t.setDaemon(daemon); return t; } } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/000077500000000000000000000000001226752375100233225ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/BooleanValue.java000066400000000000000000000014271226752375100265450ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:19 */ public interface BooleanValue { boolean getValue(); void setValue(boolean value); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/ByteValue.java000066400000000000000000000014521226752375100260670ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:19 */ public interface ByteValue { byte getValue(); void setValue(byte value); byte addValue(byte b); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/CharValue.java000066400000000000000000000014161226752375100260410ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:17 */ public interface CharValue { char getValue(); void setValue(char value); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/DoubleValue.java000066400000000000000000000015421226752375100263760ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:12 */ public interface DoubleValue { double getValue(); void setValue(double value); double addValue(double delta); double addAtomicValue(double delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/FloatValue.java000066400000000000000000000015331226752375100262310ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:15 */ public interface FloatValue { float getValue(); void setValue(float value); float addValue(float delta); float addAtomicValue(float delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/Int24Value.java000066400000000000000000000016401226752375100260630ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.constraints.Range; /** * 24-bit signed value * User: peter.lawrey * Date: 10/10/13 * Time: 07:15 */ public interface Int24Value { int getValue(); void setValue(@Range(min = -1 << 23, max = (1 << 23) - 1) int value); int addValue(int delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/Int48Value.java000066400000000000000000000016461226752375100260770ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.constraints.Range; /** * 48-bit signed value * User: peter.lawrey * Date: 10/10/13 * Time: 07:15 */ public interface Int48Value { long getValue(); void setValue(@Range(min = -1L << 47, max = (1L << 47) - 1) long value); long addValue(long delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/IntValue.java000066400000000000000000000021351226752375100257150ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:15 */ public interface IntValue { int getValue(); void setValue(int value); int addValue(int delta); int addAtomicValue(int delta); boolean compareAndSwapValue(int expected, int value); boolean tryLockValue(); boolean tryLockNanosValue(long nanos); void busyLockValue() throws InterruptedException, IllegalStateException; void unlockValue() throws IllegalMonitorStateException; } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/LongValue.java000066400000000000000000000016211226752375100260610ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:11 */ public interface LongValue { long getValue(); void setValue(long value); long addValue(long delta); long addAtomicValue(long delta); boolean compareAndSwapValue(long expected, long value); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/ShortValue.java000066400000000000000000000014631226752375100262650ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:16 */ public interface ShortValue { short getValue(); void setValue(short value); short addValue(short delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/StringValue.java000066400000000000000000000015271226752375100264350ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.constraints.MaxSize; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:13 */ public interface StringValue { String getValue(); void setValue(@MaxSize CharSequence value); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/UnsignedByteValue.java000066400000000000000000000015771226752375100275740ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.constraints.Range; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:19 */ public interface UnsignedByteValue { int getValue(); void setValue(@Range(min = 0, max = 255) int value); int addValue(int delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/UnsignedIntValue.java000066400000000000000000000016161226752375100274150ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.constraints.Range; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:19 */ public interface UnsignedIntValue { long getValue(); void setValue(@Range(min = 0, max = (1L << 32) - 1) long value); long addValue(long delta); } Java-Lang-6.1.4/lang/src/main/java/net/openhft/lang/values/UnsignedShortValue.java000066400000000000000000000016021226752375100277550ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.constraints.Range; /** * User: peter.lawrey * Date: 10/10/13 * Time: 07:19 */ public interface UnsignedShortValue { int getValue(); void setValue(@Range(min = 0, max = 65535) int value); int addValue(int delta); } Java-Lang-6.1.4/lang/src/test/000077500000000000000000000000001226752375100157635ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/000077500000000000000000000000001226752375100167045ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/000077500000000000000000000000001226752375100174725ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/000077500000000000000000000000001226752375100211355ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/000077500000000000000000000000001226752375100220565ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/JvmTest.java000066400000000000000000000016741226752375100243250ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang; import org.junit.Test; /** * User: peter.lawrey * Date: 20/09/13 * Time: 10:04 */ public class JvmTest { @Test public void testIs64Bit() { System.out.println("is64 = " + Jvm.is64Bit()); } @Test public void testGetProcessId() { System.out.println("pid = " + Jvm.getProcessId()); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/MathsTest.java000066400000000000000000000032631226752375100246410ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang; import org.junit.Test; import java.math.BigDecimal; import java.util.Random; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey * Date: 20/09/13 * Time: 10:31 */ public class MathsTest { @Test public void testIntLog2() { for (int i = 0; i < 63; i++) { long l = 1L << i; assertEquals(i, Maths.intLog2(l)); } } @Test public void testRounding() { Random rand = new Random(1); for (int i = 0; i < 1000; i++) { double d = Math.pow(1e18, rand.nextDouble()) / 1e6; BigDecimal bd = new BigDecimal(d); assertEquals(bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), Maths.round2(d), 5e-2); assertEquals(bd.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue(), Maths.round4(d), 5e-4); assertEquals(bd.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue(), Maths.round6(d), 5e-6); if (d < 1e8) assertEquals(bd.setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue(), Maths.round8(d), 5e-8); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/collection/000077500000000000000000000000001226752375100242115ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/collection/HugeArrayTest.java000066400000000000000000000054741226752375100276150ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection; import net.openhft.lang.model.JavaBeanInterface; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey * Date: 08/10/13 * Time: 08:30 */ public class HugeArrayTest { static void assertEquals2(long a, long b) { if (a != b) org.junit.Assert.assertEquals(a, b); } @Test public void testHugeArray() throws InterruptedException { // runs with a maximum heap size of 32 MB. int length = 10 * 1000 * 1000; HugeArray array = HugeCollections.newArray(JavaBeanInterface.class, length); long start = System.nanoTime(); for (int i = 0; i < array.length(); i++) { JavaBeanInterface jbi = array.get(i); // jbi.busyLockRecord(); // try { jbi.setByte((byte) i); jbi.setChar((char) i); jbi.setShort((short) i); jbi.setInt(i); jbi.setFloat(i); jbi.setLong(i); // System.nanoTime()); jbi.setDouble(i); jbi.setFlag((i & 3) == 0); jbi.setString("hello"); // } finally { // jbi.unlockRecord(); // } array.recycle(jbi); } for (int i = 0; i < array.length(); i++) { JavaBeanInterface jbi = array.get(i); // jbi.busyLockRecord(); // try { assertEquals2((byte) i, jbi.getByte()); assertEquals2((char) i, jbi.getChar()); assertEquals2((short) i, jbi.getShort()); assertEquals2(i, jbi.getInt()); assertEquals(i, jbi.getFloat(), 0); // long time = System.nanoTime() - jbi.getLong(); assertEquals2(i, jbi.getLong()); assertEquals(i, jbi.getDouble(), 0.0); assertEquals((i & 3) == 0, jbi.getFlag()); assertEquals("hello", jbi.getString()); // } finally { // jbi.unlockRecord(); // } array.recycle(jbi); } long time = System.nanoTime() - start; double avg = time / 2.0 / length; System.out.printf("Average time to access a JavaBeanInterface was %.1f ns%n", avg); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/collection/HugePricesMain.java000066400000000000000000000046301226752375100277220ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection; import net.openhft.lang.model.constraints.MaxSize; import net.openhft.lang.model.constraints.Range; import static org.junit.Assert.assertEquals; interface Price { String getInstrument(); void setInstrument(@MaxSize CharSequence instrument); TimedQuote getAsk(); void setAsk(TimedQuote ask); TimedQuote getBid(); void setBid(TimedQuote bid); } interface QuoteHeader { int getMajor(); // @Start void setMajor(@Range(min = 0, max = (1 << 24) - 1) int major); void setType(char ch); char getType(); } interface Quote extends QuoteHeader { double getPrice(); void setPrice(double price); int getAmount(); void setAmount(int amount); } interface TimedQuote extends Quote { long getTimestamp(); void setTimestamp(long price); } public class HugePricesMain { public static void main(String[] args) { int length = 1000; final HugeArray prices = HugeCollections.newArray(Price.class, length); for (int i = 0; i < length; i++) { final Price price = prices.get(i); price.setInstrument("ID" + i); price.getAsk().setPrice(100.1); price.getAsk().setAmount(1000); price.getBid().setPrice(99.8); price.getBid().setAmount(2000); prices.recycle(price); } for (int i = 0; i < length; i++) { final Price price = prices.get(i); assertEquals("ID" + i, price.getInstrument()); assertEquals(100.1, price.getAsk().getPrice(), 0.0); assertEquals(1000, price.getAsk().getAmount()); assertEquals(99.8, price.getBid().getPrice(), 0.0); assertEquals(2000, price.getBid().getAmount()); prices.recycle(price); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/collection/HugeQueueTest.java000066400000000000000000000047611226752375100276210ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.collection; import net.openhft.lang.model.JavaBeanInterface; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * User: peter.lawrey * Date: 08/10/13 * Time: 13:47 */ public class HugeQueueTest { @Test public void testQueue() { // runs with a maximum heap size of 32 MB. int tests = 5 * 1000 * 1000; int length = 1000; HugeQueue queue = HugeCollections.newQueue(JavaBeanInterface.class, length); long start = System.nanoTime(); for (int j = 0; j < tests; j += length) { for (int i = 0; i < length; i++) { JavaBeanInterface jbi = queue.offer(); jbi.setByte((byte) i); jbi.setChar((char) i); jbi.setShort((short) i); jbi.setInt(i); jbi.setFloat(i); jbi.setLong(i); jbi.setDouble(i); jbi.setFlag((i & 3) == 0); queue.recycle(jbi); } assertTrue(queue.isFull()); for (int i = 0; i < length; i++) { JavaBeanInterface jbi = queue.take(); assertEquals((byte) i, jbi.getByte()); assertEquals((char) i, jbi.getChar()); assertEquals((short) i, jbi.getShort()); assertEquals(i, jbi.getInt()); assertEquals(i, jbi.getFloat(), 0); assertEquals(i, jbi.getLong()); assertEquals(i, jbi.getDouble(), 0.0); assertEquals((i & 3) == 0, jbi.getFlag()); queue.recycle(jbi); } assertTrue(queue.isEmpty()); } long time = System.nanoTime() - start; double avg = time / 2.0 / tests; System.out.printf("Average time to access a JavaBeanInterface was %.1f ns%n", avg); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/000077500000000000000000000000001226752375100224655ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/AllocationRatesTest.java000066400000000000000000000062441226752375100272620ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.junit.Test; import java.nio.ByteBuffer; /** * User: peter Date: 24/12/13 Time: 19:43 */ /* buffers 128 KB took an average of 18,441 ns for heap ByteBuffer, 33,683 ns for direct ByteBuffer and 1,761 for DirectStore buffers 128 KB took an average of 13,062 ns for heap ByteBuffer, 17,855 ns for direct ByteBuffer and 903 for DirectStore buffers 128 KB took an average of 12,809 ns for heap ByteBuffer, 21,602 ns for direct ByteBuffer and 922 for DirectStore buffers 128 KB took an average of 10,768 ns for heap ByteBuffer, 21,444 ns for direct ByteBuffer and 894 for DirectStore buffers 128 KB took an average of 8,739 ns for heap ByteBuffer, 22,684 ns for direct ByteBuffer and 890 for DirectStore */ public class AllocationRatesTest { static final int BUFFER_SIZE = 128 * 1024; static final int ALLOCATIONS = 25000; public static final int BATCH = 10; @Test public void compareAllocationRates() { for (int i = 0; i < 5; i++) { long timeHBB = timeHeapByteBufferAllocations(); long timeDBB = timeDirectByteBufferAllocations(); long timeDS = timeDirectStoreAllocations(); System.out.printf("buffers %d KB took an average of %,d ns for heap ByteBuffer, %,d ns for direct ByteBuffer and %,d for DirectStore%n", BUFFER_SIZE / 1024, timeHBB / ALLOCATIONS, timeDBB / ALLOCATIONS, timeDS / ALLOCATIONS ); } } private long timeHeapByteBufferAllocations() { long start = System.nanoTime(); for (int i = 0; i < ALLOCATIONS; i += BATCH) { ByteBuffer[] bb = new ByteBuffer[BATCH]; for (int j = 0; j < BATCH; j++) bb[j] = ByteBuffer.allocate(BUFFER_SIZE); } return System.nanoTime() - start; } private long timeDirectByteBufferAllocations() { long start = System.nanoTime(); for (int i = 0; i < ALLOCATIONS; i += BATCH) { ByteBuffer[] bb = new ByteBuffer[BATCH]; for (int j = 0; j < BATCH; j++) bb[j] = ByteBuffer.allocateDirect(BUFFER_SIZE); } return System.nanoTime() - start; } private long timeDirectStoreAllocations() { long start = System.nanoTime(); for (int i = 0; i < ALLOCATIONS; i += BATCH) { DirectStore[] ds = new DirectStore[BATCH]; for (int j = 0; j < BATCH; j++) ds[j] = DirectStore.allocateLazy(BUFFER_SIZE); for (int j = 0; j < BATCH; j++) ds[j].free(); } return System.nanoTime() - start; } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/ByteBufferBytesTest.java000066400000000000000000000740161226752375100272440ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.Maths; import net.openhft.lang.thread.NamedThreadFactory; import org.junit.Before; import org.junit.Test; import java.io.*; import java.math.BigDecimal; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.*; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import static net.openhft.lang.io.StopCharTesters.CONTROL_STOP; import static net.openhft.lang.io.StopCharTesters.SPACE_STOP; import static org.junit.Assert.*; /** * Created with IntelliJ IDEA. User: peter.lawrey Date: 17/09/13 Time: 16:09 To change this template use File | Settings | File * Templates. */ public class ByteBufferBytesTest { public static final int SIZE = 128; private ByteBufferBytes bytes; private ByteBuffer byteBuffer; @Before public void beforeTest() { byteBuffer = ByteBuffer.allocate(SIZE).order(ByteOrder.nativeOrder()); bytes = new ByteBufferBytes(byteBuffer); } @Test public void testLongHash() throws Exception { byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8}; long h = NativeBytes.longHash(bytes, 0, bytes.length); assertFalse(h == 0); byte[] bytes2 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; long h2 = NativeBytes.longHash(bytes2, 0, bytes2.length); assertFalse(h2 == 0); assertFalse(h2 == h); } @Test public void testRead() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.writeByte(i, i); bytes.position(0); for (int i = 0; i < bytes.capacity(); i++) assertEquals((byte) i, bytes.read()); for (int i = (int) (bytes.capacity() - 1); i >= 0; i--) { assertEquals((byte) i, bytes.readByte(i)); } } @Test public void testReadFully() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.write(i); bytes.position(0); byte[] bytes = new byte[(int) this.bytes.capacity()]; this.bytes.readFully(bytes); for (int i = 0; i < this.bytes.capacity(); i++) assertEquals((byte) i, bytes[i]); } @Test public void testCompareAndSetLong() throws Exception { assertTrue(bytes.compareAndSwapLong(0, 0, 1)); assertFalse(bytes.compareAndSwapLong(0, 0, 1)); assertTrue(bytes.compareAndSwapLong(8, 0, 1)); assertTrue(bytes.compareAndSwapLong(0, 1, 2)); } @Test public void testPosition() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.write(i); for (int i = (int) (bytes.capacity() - 1); i >= 0; i--) { bytes.position(i); assertEquals((byte) i, bytes.read()); } } @Test public void testCapacity() throws Exception { assertEquals(SIZE, bytes.capacity()); assertEquals(10, new NativeBytes(0, 0, 10).capacity()); } @Test public void testRemaining() throws Exception { assertEquals(SIZE, bytes.remaining()); bytes.position(10); assertEquals(SIZE - 10, bytes.remaining()); } @Test public void testByteOrder() throws Exception { assertEquals(ByteOrder.nativeOrder(), bytes.byteOrder()); } @Test public void testCheckEndOfBuffer() throws Exception { bytes.checkEndOfBuffer(); bytes.position(SIZE + 2); try { bytes.checkEndOfBuffer(); fail(); } catch (IndexOutOfBoundsException expected) { } } @Test public void testAppendDouble() { testAppendDouble0(-6.895305375646115E24); Random random = new Random(1); for (int i = 0; i < 100000; i++) { double d = Math.pow(1e32, random.nextDouble()) / 1e6; if (i % 3 == 0) d = -d; testAppendDouble0(d); } } private void testAppendDouble0(double d) { bytes.position(0); bytes.append(d).append(' '); bytes.position(0); double d2 = bytes.parseDouble(); assertEquals(d, d2, 0); } @Test public void testAppendDouble2() { // testAppendDouble0(-0.93879148954440506, 14); // testAppendDouble0(-0.214980202661, 12); // testAppendDouble0(-0.937082148896, 12); testAppendDouble0(0.17805, 5); Random random = new Random(1); for (int j = 0; j < 20000; j++) { double d = random.nextDouble(); if (j % 3 == 0) d = -d; // if (j % 5 == 0) d *= 1e6; for (int i = 0; i < 4; i++) { testAppendDouble0(d, i); } } } private void testAppendDouble0(double d, int precision) { bytes.position(0); bytes.append(d, precision).append(' '); bytes.position(0); String text = bytes.parseUTF(SPACE_STOP); bytes.position(0); assertEquals(0, bytes.position()); double d2 = bytes.parseDouble(); double d3 = (double) Math.round(d * Maths.power10(precision)) / Maths.power10(precision); // if (precision >= 14) // assertEquals("'" + text + "' p: " + precision + " v: " + new BigDecimal(d), d3, d2, 5e-29 * Maths.power10(precision)); // else assertEquals("'" + text + "' p: " + precision, d3, d2, 0); } @Test public void testWriteReadBytes() { byte[] bytes = "Hello World!".getBytes(); this.bytes.write(bytes); byte[] bytes2 = new byte[bytes.length]; this.bytes.position(0); this.bytes.read(bytes2); assertTrue(Arrays.equals(bytes, bytes2)); this.bytes.write(22, bytes); byte[] bytes3 = new byte[bytes.length]; this.bytes.skipBytes((int) (22 - this.bytes.position())); assertEquals(bytes3.length, this.bytes.read(bytes3)); assertTrue(Arrays.equals(bytes, bytes3)); this.bytes.position(this.bytes.capacity()); assertEquals(-1, this.bytes.read(bytes3)); } @Test public void testWriteReadUTFΔ() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.writeUTFΔ(word); } bytes.writeUTFΔ(null); bytes.position(0); for (String word : words) { assertEquals(word, bytes.readUTFΔ()); } assertEquals(null, bytes.readUTFΔ()); assertEquals("", bytes.readUTFΔ()); assertEquals(26, bytes.position()); // check the size bytes.position(0); StringBuilder sb = new StringBuilder(); for (String word : words) { assertTrue(bytes.readUTFΔ(sb)); assertEquals(word, sb.toString()); } assertFalse(bytes.readUTFΔ(sb)); assertTrue(bytes.readUTFΔ(sb)); assertEquals("", sb.toString()); } @Test public void testWriteReadUTF() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.writeUTF(word); } bytes.writeUTF(""); assertEquals(28, bytes.position()); // check the size, more bytes for less strings than writeUTFΔ bytes.position(0); for (String word : words) { assertEquals(word, bytes.readUTF()); } assertEquals("", bytes.readUTF()); } @Test public void testAppendParseUTF() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.append(word).append('\t'); } bytes.append('\t'); bytes.position(0); for (String word : words) { assertEquals(word, bytes.parseUTF(CONTROL_STOP)); } assertEquals("", bytes.parseUTF(CONTROL_STOP)); bytes.position(0); StringBuilder sb = new StringBuilder(); for (String word : words) { bytes.parseUTF(sb, CONTROL_STOP); assertEquals(word, sb.toString()); } bytes.parseUTF(sb, CONTROL_STOP); assertEquals("", sb.toString()); bytes.position(0); bytes.skipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(13, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(17, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(18, bytes.position()); bytes.position(0); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.position(10); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(13, bytes.position()); } @Test public void testWriteReadLines() { byte[] bytes = "Hello\nWorld!\r\nBye".getBytes(); this.bytes.write(bytes); this.bytes.position(0); assertEquals("Hello", this.bytes.readLine()); assertEquals("World!", this.bytes.readLine()); assertTrue(this.bytes.readLine().startsWith("Bye")); } @Test public void testWriteReadByteBuffer() { byte[] bytes = "Hello\nWorld!\r\nBye".getBytes(); this.bytes.write(ByteBuffer.wrap(bytes)); this.bytes.position(0); byte[] bytes2 = new byte[bytes.length + 1]; ByteBuffer bb2 = ByteBuffer.wrap(bytes2); this.bytes.read(bb2); assertEquals(bytes2.length, bb2.position()); assertTrue(Arrays.equals(bytes, Arrays.copyOf(bytes2, bytes.length))); } @Test public void testReadWriteBoolean() { for (int i = 0; i < 32; i++) bytes.writeBoolean(i, (i & 3) == 0); bytes.position(32); for (int i = 32; i < 64; i++) bytes.writeBoolean((i & 5) == 0); bytes.position(0); for (int i = 0; i < 32; i++) assertEquals((i & 3) == 0, bytes.readBoolean()); for (int i = 32; i < 64; i++) assertEquals((i & 5) == 0, bytes.readBoolean(i)); } @Test public void testReadWriteShort() { for (int i = 0; i < 32; i += 2) bytes.writeShort(i, i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeShort(i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(i, bytes.readShort()); for (int i = 32; i < 64; i += 2) assertEquals(i, bytes.readShort(i)); } @Test public void testReadWriteCompactShort() { int[] ints = {Short.MIN_VALUE, Short.MAX_VALUE, -125, 0, 127, -10000, 10000}; for (int i : ints) { bytes.writeCompactShort(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 + 2 * 3, bytes.position()); bytes.position(0); for (int i : ints) assertEquals(i, bytes.readCompactShort()); } @Test public void testReadWriteCompactInt() { int[] ints = {-10000000, Integer.MIN_VALUE, Integer.MAX_VALUE, Short.MIN_VALUE + 3, 0, Short.MAX_VALUE, 10000000}; for (int i : ints) { bytes.writeCompactInt(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 * 2 + 2 * 6, bytes.position()); bytes.position(0); for (int i : ints) assertEquals(i, bytes.readCompactInt()); } @Test public void testReadWriteCompactLong() { long[] ints = {Long.MAX_VALUE, -100000000000L, Long.MIN_VALUE, Integer.MIN_VALUE + 3, 0, Integer.MAX_VALUE, 100000000000L}; for (long i : ints) { bytes.writeCompactLong(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 * 4 + 2 * 12, bytes.position()); bytes.position(0); for (long i : ints) assertEquals(i, bytes.readCompactLong()); } @Test public void testReadWriteCompactDouble() { double[] doubles = {1, 1000, 1000000, -100000000, 0.1f, 0.1, 0.5, 0.51}; for (double i : doubles) { bytes.writeCompactDouble(i); // System.out.println(i + " " + bytes.position()); } assertEquals(6 * 4 + 2 * 12, bytes.position()); bytes.position(0); for (double i : doubles) assertEquals(i, bytes.readCompactDouble(), 0.0); } @Test public void testReadWriteStop() { long[] longs = {Long.MIN_VALUE, Long.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE}; for (long i : longs) { bytes.writeStopBit(i); // System.out.println(i + " " + bytes.position()); } assertEquals(9 + 10, +5 + 6, bytes.position()); bytes.position(0); for (long i : longs) assertEquals(i, bytes.readStopBit()); } @Test public void testReadWriteChar() { for (int i = 0; i < 32; i += 2) bytes.writeChar(i, i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeChar(i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(i, bytes.readChar()); for (int i = 32; i < 64; i += 2) assertEquals(i, bytes.readChar(i)); } @Test public void testReadWriteUnsignedShort() { for (int i = 0; i < 32; i += 2) bytes.writeUnsignedShort(i, ~i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeUnsignedShort(~i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(~i & 0xFFFF, bytes.readUnsignedShort()); for (int i = 32; i < 64; i += 2) assertEquals(~i & 0xFFFF, bytes.readUnsignedShort(i)); } @Test public void testReadWriteInt() { for (int i = 0; i < 32; i += 4) bytes.writeInt(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeInt(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readInt()); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readInt(i)); } @Test public void testReadWriteThreadeSafeInt() { for (int i = 0; i < 32; i += 4) bytes.writeOrderedInt(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeOrderedInt(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readVolatileInt()); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readVolatileInt(i)); } @Test public void testReadWriteFloat() { for (int i = 0; i < 32; i += 4) bytes.writeFloat(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeFloat(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readFloat(), 0); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readFloat(i), 0); } @Test public void testReadWriteUnsignedInt() { for (int i = 0; i < 32; i += 4) bytes.writeUnsignedInt(i, ~i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeUnsignedInt(~i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(~i & 0xFFFFFFFFL, bytes.readUnsignedInt()); for (int i = 32; i < 64; i += 4) assertEquals(~i & 0xFFFFFFFFL, bytes.readUnsignedInt(i)); } @Test public void testReadWriteInt24() { for (int i = 0; i < 30; i += 3) bytes.writeInt24(i, ~i & 0x7FFFFF); bytes.position(30); for (int i = 30; i < 63; i += 3) bytes.writeInt24(~i & 0x7FFFFF); assertEquals(63, bytes.position()); bytes.position(0); for (int i = 0; i < 30; i += 3) assertEquals("i: " + i, ~i & 0x7FFFFFL, bytes.readInt24()); for (int i = 30; i < 63; i += 3) assertEquals("i: " + i, ~i & 0x7FFFFFL, bytes.readInt24(i)); // now negative bytes.position(0); for (int i = 0; i < 30; i += 3) bytes.writeInt24(i, ~i); bytes.position(30); for (int i = 30; i < 63; i += 3) bytes.writeInt24(~i); assertEquals(63, bytes.position()); bytes.position(0); for (int i = 0; i < 30; i += 3) assertEquals("i: " + i, ~i << 8 >> 8, bytes.readInt24()); for (int i = 30; i < 63; i += 3) assertEquals("i: " + i, ~i << 8 >> 8, bytes.readInt24(i)); } @Test public void testReadWriteInt48() { for (long i = 0; i < 30; i += 6) bytes.writeInt48(i, ~i & 0x7FFFFFFFFFFFL); bytes.position(30); for (long i = 30; i < 60; i += 6) bytes.writeInt48(~i & 0x7FFFFFFFFFFFL); assertEquals(60, bytes.position()); bytes.position(0); for (long i = 0; i < 30; i += 6) assertEquals("i: " + i, ~i & 0x7FFFFFFFFFFFL, bytes.readInt48()); for (long i = 30; i < 60; i += 6) assertEquals("i: " + i, ~i & 0x7FFFFFFFFFFFL, bytes.readInt48(i)); // now negative bytes.position(0); for (long i = 0; i < 30; i += 6) bytes.writeInt48(i, ~i); bytes.position(30); for (long i = 30; i < 60; i += 6) bytes.writeInt48(~i); assertEquals(60, bytes.position()); bytes.position(0); for (long i = 0; i < 30; i += 6) assertEquals("i: " + i, ~i << 16 >> 16, bytes.readInt48()); for (long i = 30; i < 60; i += 6) assertEquals("i: " + i, ~i << 16 >> 16, bytes.readInt48(i)); } @Test public void testDateTimes() { long now = System.currentTimeMillis(); bytes.appendDateTimeMillis(now); bytes.append(' '); bytes.appendDateMillis(now); bytes.append('T'); bytes.appendTimeMillis(now % 86400000L); assertEquals(23 * 2 + 1, bytes.position()); bytes.position(0); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); String asStr = sdf.format(new Date(now)); assertEquals(asStr, bytes.parseUTF(SPACE_STOP)); assertEquals(asStr, bytes.parseUTF(SPACE_STOP)); } @Test public void testReadWriteCompactUnsignedShort() { for (int i = 0; i < 64; i += 4) bytes.writeCompactUnsignedShort(i); assertEquals(64 / 4, bytes.position()); bytes.position(0); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readByte(i / 4)); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readCompactUnsignedShort()); } @Test public void testReadWriteCompactUnsignedInt() { for (int i = 0; i < 64; i += 4) bytes.writeCompactUnsignedInt(i); assertEquals(64 / 2, bytes.position()); bytes.position(0); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readShort(i / 2)); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readCompactUnsignedInt()); } @Test public void testReadWriteLong() { for (long i = 0; i < 32; i += 8) bytes.writeLong(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeLong(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readLong()); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readLong(i)); } @Test public void testReadWriteThreadSafeLong() { for (long i = 0; i < 32; i += 8) bytes.writeOrderedLong(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeOrderedLong(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readVolatileLong()); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readVolatileLong(i)); } @Test public void testReadWriteDouble() { for (long i = 0; i < 32; i += 8) bytes.writeDouble(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeDouble(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readDouble(), 0); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readDouble(i), 0); } @Test public void testAppendSubstring() { bytes.append("Hello World", 2, 7).append("\n"); bytes.position(0); assertEquals("Hello World".substring(2, 7), bytes.parseUTF(CONTROL_STOP)); } @Test public void testWriteReadEnum() { bytes.append(BuySell.Buy).append("\t").append(BuySell.Sell); bytes.position(0); assertEquals(BuySell.Buy, bytes.parseEnum(BuySell.class, CONTROL_STOP)); assertEquals(BuySell.Sell, bytes.parseEnum(BuySell.class, CONTROL_STOP)); assertEquals(null, bytes.parseEnum(BuySell.class, CONTROL_STOP)); } @Test public void testAppendParse() { bytes.append(false).append(' '); bytes.append(true).append(' '); bytes.append("what?").append(' '); bytes.append("word£€").append(' '); bytes.append(BuySell.Buy).append(' '); bytes.append(1234).append(' '); bytes.append(123456L).append(' '); bytes.append(1.2345).append(' '); bytes.append(1.5555, 3).append(' '); bytes.position(0); assertEquals(false, bytes.parseBoolean(SPACE_STOP)); assertEquals(true, bytes.parseBoolean(SPACE_STOP)); assertEquals(null, bytes.parseBoolean(SPACE_STOP)); assertEquals("word£€", bytes.parseUTF(SPACE_STOP)); assertEquals(BuySell.Buy, bytes.parseEnum(BuySell.class, SPACE_STOP)); assertEquals(1234, bytes.parseLong()); assertEquals(123456L, bytes.parseLong()); assertEquals(1.2345, bytes.parseDouble(), 0); assertEquals(1.556, bytes.parseDouble(), 0); } @Test public void testWriteByteChar() throws UnsupportedEncodingException { bytes.writeBytes("Hello \u00ff\u01fe\u02fc\n"); bytes.writeChars("Hello \u00ff\u01fe\u02fc\n"); byte[] bytes = new byte[(int) this.bytes.position()]; this.bytes.position(0); this.bytes.readFully(bytes); assertEquals("Hello \u00ff\u00fe\u00fc\n" + "H\u0000e\u0000l\u0000l\u0000o\u0000 \u0000ÿ\u0000þ\u0001ü\u0002\n" + "\u0000", new String(bytes, "ISO-8859-1")); } @Test public void testWriteBytes() { bytes.write("Hello World\n".getBytes(), 0, 10); bytes.write("good bye\n".getBytes(), 4, 4); bytes.write(4, "0 w".getBytes()); bytes.position(0); assertEquals("Hell0 worl bye", bytes.parseUTF(CONTROL_STOP)); } @Test public void testAppendIterable() { bytes.append(Arrays.asList(1, 2, 3, 4, 5), ";").append(' '); bytes.append(new TreeSet(Arrays.asList(21, 2, 13, 4, 5)), ";"); bytes.position(0); assertEquals("1;2;3;4;5 2;4;5;13;21", bytes.parseUTF(CONTROL_STOP)); } @Test public void readWriteMutableDecimal() { Random rand = new Random(2); MutableDecimal md = new MutableDecimal(); MutableDecimal md2 = new MutableDecimal(); // md.set(1260042744, 0); for (int i = 0; i < 20000; i++) { int n = rand.nextInt(); for (int j = 0; j < 6; j++) { testDecimal0(md, md2, n, j); } } } private void testDecimal0(MutableDecimal md, MutableDecimal md2, int n, int j) { md.set(n, j); bytes.position(0); bytes.append(md).append('\n'); bytes.position(0); bytes.parseDecimal(md2); bytes.position(0); String text = bytes.parseUTF(CONTROL_STOP); if (!md.equals(md2)) assertEquals("n: " + n + ", s: " + j + " t: " + text, md, md2); } @Test public void testStream() throws IOException { bytes = new ByteBufferBytes(ByteBuffer.allocate(1000)); GZIPOutputStream out = new GZIPOutputStream(bytes.outputStream()); out.write("Hello world\n".getBytes()); out.close(); bytes.position(0); GZIPInputStream in = new GZIPInputStream(bytes.inputStream()); byte[] bytes = new byte[12]; for (int i = 0; i < 12; i++) bytes[i] = (byte) in.read(); assertEquals(-1, in.read()); assertEquals("Hello world\n", new String(bytes)); in.close(); } @Test public void testStream2() throws IOException { OutputStream out = bytes.outputStream(); out.write(11); out.write(22); out.write(33); out.write(44); out.write(55); bytes.position(0); InputStream in = bytes.inputStream(); assertTrue(in.markSupported()); assertEquals(11, in.read()); in.mark(1); assertEquals(1, bytes.position()); assertEquals(22, in.read()); assertEquals(2, bytes.position()); assertEquals(33, in.read()); in.reset(); assertEquals(1, bytes.position()); assertEquals(22, in.read()); assertEquals(2, in.skip(2)); assertEquals(4, bytes.position()); assertEquals(SIZE - 4, bytes.available()); assertEquals(55, in.read()); in.close(); } @Test public void testWriteObject() { for (Object o : new Object[]{10, 9.9, "string", new Date(), BigDecimal.valueOf(1.1)}) { bytes.position(0); bytes.writeObject(o); // System.out.println(o +" size: "+bytes.position()); assertTrue(bytes.position() < 21); bytes.position(0); Object o2 = bytes.readObject(); bytes.position(0); Object o3 = bytes.readObject(o.getClass()); assertEquals(o, o2); assertEquals(o, o3); } } @Test public void testWriteSerializable() { int capacity = 16 * 1024; byteBuffer = ByteBuffer.allocateDirect(capacity); bytes = new ByteBufferBytes(byteBuffer); Calendar cal = Calendar.getInstance(); bytes.writeObject(cal); Dummy d = new Dummy(); bytes.writeObject(d); bytes.position(0); Calendar cal2 = bytes.readObject(Calendar.class); Dummy d2 = bytes.readObject(Dummy.class); assertEquals(cal, cal2); assertEquals(d, d2); } @Test public void testAddAndGet() { for (int i = 0; i < 10; i++) bytes.addAndGetInt(0L, 10); assertEquals(100, bytes.readInt(0L)); assertEquals(0, bytes.readInt(4L)); for (int i = 0; i < 11; i++) bytes.getAndAdd(4L, 11); assertEquals(100, bytes.readInt(0L)); assertEquals(11 * 11, bytes.readInt(4L)); } enum BuySell { Buy, Sell } static class Dummy implements Serializable { @Override public boolean equals(Object obj) { return obj instanceof Dummy; } } @Test public void testErrors() { int capacity = 1024; byteBuffer = ByteBuffer.allocate(capacity); // it is actually much bigger than it believes bytes = new ByteBufferBytes(byteBuffer, 0, 16); bytes.writeLong(8); assertFalse(bytes.isFinished()); bytes.finish(); assertTrue(bytes.isFinished()); bytes.flush(); bytes.writeLong(16); bytes.finish(); bytes.flush(); try { bytes.writeLong(24); fail(); } catch (IndexOutOfBoundsException expected) { } bytes.finish(); bytes.flush(); bytes.reset(); assertEquals(0, bytes.position()); assertEquals(8, bytes.skip(8)); assertEquals(8, bytes.position()); bytes.writeLong(22); bytes.close(); } @Test public void testWriteList() { List ints = Arrays.asList(1, 2, 3, 4); bytes.writeList(ints); bytes.reset(); List ints2 = new ArrayList(); bytes.readList(ints2, Integer.class); assertEquals(ints, ints2); bytes.reset(); List words = Arrays.asList("Hello word byte for now".split(" ")); bytes.writeList(words); bytes.reset(); List words2 = new ArrayList(); bytes.readList(words2, String.class); } @Test public void testWriteMap() { Map map = new LinkedHashMap() { { put("one", 1); put("two", 2); put("three", 3); put("four", 4); } }; bytes.writeMap(map); bytes.finish(); bytes.reset(); Map map2 = new LinkedHashMap(); bytes.readMap(map2, String.class, Integer.class); assertEquals(map, map2); } @Test public void unloadFailed() throws InterruptedException { bytes.busyLockInt(0); ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("unloadFailed")); Future future = es.submit(new Callable() { @Override public Void call() throws Exception { bytes.unlockInt(0); return null; } }); es.shutdown(); try { future.get(); fail(); } catch (ExecutionException e) { assertEquals(IllegalMonitorStateException.class, e.getCause().getClass()); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/DirectByteBufferBytesTest.java000066400000000000000000000740471226752375100304030ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.Maths; import net.openhft.lang.thread.NamedThreadFactory; import org.junit.Before; import org.junit.Test; import java.io.*; import java.math.BigDecimal; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.*; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import static net.openhft.lang.io.StopCharTesters.CONTROL_STOP; import static net.openhft.lang.io.StopCharTesters.SPACE_STOP; import static org.junit.Assert.*; /** * Created with IntelliJ IDEA. User: peter.lawrey Date: 17/09/13 Time: 16:09 To change this template use File | Settings | File * Templates. */ public class DirectByteBufferBytesTest { public static final int SIZE = 128; private ByteBufferBytes bytes; private ByteBuffer byteBuffer; @Before public void beforeTest() { byteBuffer = ByteBuffer.allocateDirect(SIZE).order(ByteOrder.nativeOrder()); bytes = new ByteBufferBytes(byteBuffer); } @Test public void testLongHash() throws Exception { byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8}; long h = NativeBytes.longHash(bytes, 0, bytes.length); assertFalse(h == 0); byte[] bytes2 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; long h2 = NativeBytes.longHash(bytes2, 0, bytes2.length); assertFalse(h2 == 0); assertFalse(h2 == h); } @Test public void testRead() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.writeByte(i, i); bytes.position(0); for (int i = 0; i < bytes.capacity(); i++) assertEquals((byte) i, bytes.read()); for (int i = (int) (bytes.capacity() - 1); i >= 0; i--) { assertEquals((byte) i, bytes.readByte(i)); } } @Test public void testReadFully() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.write(i); bytes.position(0); byte[] bytes = new byte[(int) this.bytes.capacity()]; this.bytes.readFully(bytes); for (int i = 0; i < this.bytes.capacity(); i++) assertEquals((byte) i, bytes[i]); } @Test public void testCompareAndSetLong() throws Exception { assertTrue(bytes.compareAndSwapLong(0, 0, 1)); assertFalse(bytes.compareAndSwapLong(0, 0, 1)); assertTrue(bytes.compareAndSwapLong(8, 0, 1)); assertTrue(bytes.compareAndSwapLong(0, 1, 2)); } @Test public void testPosition() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.write(i); for (int i = (int) (bytes.capacity() - 1); i >= 0; i--) { bytes.position(i); assertEquals((byte) i, bytes.read()); } } @Test public void testCapacity() throws Exception { assertEquals(SIZE, bytes.capacity()); assertEquals(10, new NativeBytes(0, 0, 10).capacity()); } @Test public void testRemaining() throws Exception { assertEquals(SIZE, bytes.remaining()); bytes.position(10); assertEquals(SIZE - 10, bytes.remaining()); } @Test public void testByteOrder() throws Exception { assertEquals(ByteOrder.nativeOrder(), bytes.byteOrder()); } @Test public void testCheckEndOfBuffer() throws Exception { bytes.checkEndOfBuffer(); bytes.position(SIZE + 2); try { bytes.checkEndOfBuffer(); fail(); } catch (IndexOutOfBoundsException expected) { } } @Test public void testAppendDouble() { testAppendDouble0(-6.895305375646115E24); Random random = new Random(1); for (int i = 0; i < 100000; i++) { double d = Math.pow(1e32, random.nextDouble()) / 1e6; if (i % 3 == 0) d = -d; testAppendDouble0(d); } } private void testAppendDouble0(double d) { bytes.position(0); bytes.append(d).append(' '); bytes.position(0); double d2 = bytes.parseDouble(); assertEquals(d, d2, 0); } @Test public void testAppendDouble2() { // testAppendDouble0(-0.93879148954440506, 14); // testAppendDouble0(-0.214980202661, 12); // testAppendDouble0(-0.937082148896, 12); testAppendDouble0(0.17805, 5); Random random = new Random(1); for (int j = 0; j < 20000; j++) { double d = random.nextDouble(); if (j % 3 == 0) d = -d; // if (j % 5 == 0) d *= 1e6; for (int i = 0; i < 4; i++) { testAppendDouble0(d, i); } } } private void testAppendDouble0(double d, int precision) { bytes.position(0); bytes.append(d, precision).append(' '); bytes.position(0); String text = bytes.parseUTF(SPACE_STOP); bytes.position(0); assertEquals(0, bytes.position()); double d2 = bytes.parseDouble(); double d3 = (double) Math.round(d * Maths.power10(precision)) / Maths.power10(precision); // if (precision >= 14) // assertEquals("'" + text + "' p: " + precision + " v: " + new BigDecimal(d), d3, d2, 5e-29 * Maths.power10(precision)); // else assertEquals("'" + text + "' p: " + precision, d3, d2, 0); } @Test public void testWriteReadBytes() { byte[] bytes = "Hello World!".getBytes(); this.bytes.write(bytes); byte[] bytes2 = new byte[bytes.length]; this.bytes.position(0); this.bytes.read(bytes2); assertTrue(Arrays.equals(bytes, bytes2)); this.bytes.write(22, bytes); byte[] bytes3 = new byte[bytes.length]; this.bytes.skipBytes((int) (22 - this.bytes.position())); assertEquals(bytes3.length, this.bytes.read(bytes3)); assertTrue(Arrays.equals(bytes, bytes3)); this.bytes.position(this.bytes.capacity()); assertEquals(-1, this.bytes.read(bytes3)); } @Test public void testWriteReadUTFΔ() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.writeUTFΔ(word); } bytes.writeUTFΔ(null); bytes.position(0); for (String word : words) { assertEquals(word, bytes.readUTFΔ()); } assertEquals(null, bytes.readUTFΔ()); assertEquals("", bytes.readUTFΔ()); assertEquals(26, bytes.position()); // check the size bytes.position(0); StringBuilder sb = new StringBuilder(); for (String word : words) { assertTrue(bytes.readUTFΔ(sb)); assertEquals(word, sb.toString()); } assertFalse(bytes.readUTFΔ(sb)); assertTrue(bytes.readUTFΔ(sb)); assertEquals("", sb.toString()); } @Test public void testWriteReadUTF() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.writeUTF(word); } bytes.writeUTF(""); assertEquals(28, bytes.position()); // check the size, more bytes for less strings than writeUTFΔ bytes.position(0); for (String word : words) { assertEquals(word, bytes.readUTF()); } assertEquals("", bytes.readUTF()); } @Test public void testAppendParseUTF() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.append(word).append('\t'); } bytes.append('\t'); bytes.position(0); for (String word : words) { assertEquals(word, bytes.parseUTF(CONTROL_STOP)); } assertEquals("", bytes.parseUTF(CONTROL_STOP)); bytes.position(0); StringBuilder sb = new StringBuilder(); for (String word : words) { bytes.parseUTF(sb, CONTROL_STOP); assertEquals(word, sb.toString()); } bytes.parseUTF(sb, CONTROL_STOP); assertEquals("", sb.toString()); bytes.position(0); bytes.skipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(13, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(17, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(18, bytes.position()); bytes.position(0); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.position(10); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(13, bytes.position()); } @Test public void testWriteReadLines() { byte[] bytes = "Hello\nWorld!\r\nBye".getBytes(); this.bytes.write(bytes); this.bytes.position(0); assertEquals("Hello", this.bytes.readLine()); assertEquals("World!", this.bytes.readLine()); assertTrue(this.bytes.readLine().startsWith("Bye")); } @Test public void testWriteReadByteBuffer() { byte[] bytes = "Hello\nWorld!\r\nBye".getBytes(); this.bytes.write(ByteBuffer.wrap(bytes)); this.bytes.position(0); byte[] bytes2 = new byte[bytes.length + 1]; ByteBuffer bb2 = ByteBuffer.wrap(bytes2); this.bytes.read(bb2); assertEquals(bytes2.length, bb2.position()); assertTrue(Arrays.equals(bytes, Arrays.copyOf(bytes2, bytes.length))); } @Test public void testReadWriteBoolean() { for (int i = 0; i < 32; i++) bytes.writeBoolean(i, (i & 3) == 0); bytes.position(32); for (int i = 32; i < 64; i++) bytes.writeBoolean((i & 5) == 0); bytes.position(0); for (int i = 0; i < 32; i++) assertEquals((i & 3) == 0, bytes.readBoolean()); for (int i = 32; i < 64; i++) assertEquals((i & 5) == 0, bytes.readBoolean(i)); } @Test public void testReadWriteShort() { for (int i = 0; i < 32; i += 2) bytes.writeShort(i, i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeShort(i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(i, bytes.readShort()); for (int i = 32; i < 64; i += 2) assertEquals(i, bytes.readShort(i)); } @Test public void testReadWriteCompactShort() { int[] ints = {Short.MIN_VALUE, Short.MAX_VALUE, -125, 0, 127, -10000, 10000}; for (int i : ints) { bytes.writeCompactShort(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 + 2 * 3, bytes.position()); bytes.position(0); for (int i : ints) assertEquals(i, bytes.readCompactShort()); } @Test public void testReadWriteCompactInt() { int[] ints = {-10000000, Integer.MIN_VALUE, Integer.MAX_VALUE, Short.MIN_VALUE + 3, 0, Short.MAX_VALUE, 10000000}; for (int i : ints) { bytes.writeCompactInt(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 * 2 + 2 * 6, bytes.position()); bytes.position(0); for (int i : ints) assertEquals(i, bytes.readCompactInt()); } @Test public void testReadWriteCompactLong() { long[] ints = {Long.MAX_VALUE, -100000000000L, Long.MIN_VALUE, Integer.MIN_VALUE + 3, 0, Integer.MAX_VALUE, 100000000000L}; for (long i : ints) { bytes.writeCompactLong(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 * 4 + 2 * 12, bytes.position()); bytes.position(0); for (long i : ints) assertEquals(i, bytes.readCompactLong()); } @Test public void testReadWriteCompactDouble() { double[] doubles = {1, 1000, 1000000, -100000000, 0.1f, 0.1, 0.5, 0.51}; for (double i : doubles) { bytes.writeCompactDouble(i); // System.out.println(i + " " + bytes.position()); } assertEquals(6 * 4 + 2 * 12, bytes.position()); bytes.position(0); for (double i : doubles) assertEquals(i, bytes.readCompactDouble(), 0.0); } @Test public void testReadWriteStop() { long[] longs = {Long.MIN_VALUE, Long.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE}; for (long i : longs) { bytes.writeStopBit(i); // System.out.println(i + " " + bytes.position()); } assertEquals(9 + 10, +5 + 6, bytes.position()); bytes.position(0); for (long i : longs) assertEquals(i, bytes.readStopBit()); } @Test public void testReadWriteChar() { for (int i = 0; i < 32; i += 2) bytes.writeChar(i, i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeChar(i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(i, bytes.readChar()); for (int i = 32; i < 64; i += 2) assertEquals(i, bytes.readChar(i)); } @Test public void testReadWriteUnsignedShort() { for (int i = 0; i < 32; i += 2) bytes.writeUnsignedShort(i, ~i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeUnsignedShort(~i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(~i & 0xFFFF, bytes.readUnsignedShort()); for (int i = 32; i < 64; i += 2) assertEquals(~i & 0xFFFF, bytes.readUnsignedShort(i)); } @Test public void testReadWriteInt() { for (int i = 0; i < 32; i += 4) bytes.writeInt(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeInt(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readInt()); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readInt(i)); } @Test public void testReadWriteThreadeSafeInt() { for (int i = 0; i < 32; i += 4) bytes.writeOrderedInt(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeOrderedInt(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readVolatileInt()); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readVolatileInt(i)); } @Test public void testReadWriteFloat() { for (int i = 0; i < 32; i += 4) bytes.writeFloat(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeFloat(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readFloat(), 0); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readFloat(i), 0); } @Test public void testReadWriteUnsignedInt() { for (int i = 0; i < 32; i += 4) bytes.writeUnsignedInt(i, ~i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeUnsignedInt(~i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(~i & 0xFFFFFFFFL, bytes.readUnsignedInt()); for (int i = 32; i < 64; i += 4) assertEquals(~i & 0xFFFFFFFFL, bytes.readUnsignedInt(i)); } @Test public void testReadWriteInt24() { for (int i = 0; i < 30; i += 3) bytes.writeInt24(i, ~i & 0x7FFFFF); bytes.position(30); for (int i = 30; i < 63; i += 3) bytes.writeInt24(~i & 0x7FFFFF); assertEquals(63, bytes.position()); bytes.position(0); for (int i = 0; i < 30; i += 3) assertEquals("i: " + i, ~i & 0x7FFFFFL, bytes.readInt24()); for (int i = 30; i < 63; i += 3) assertEquals("i: " + i, ~i & 0x7FFFFFL, bytes.readInt24(i)); // now negative bytes.position(0); for (int i = 0; i < 30; i += 3) bytes.writeInt24(i, ~i); bytes.position(30); for (int i = 30; i < 63; i += 3) bytes.writeInt24(~i); assertEquals(63, bytes.position()); bytes.position(0); for (int i = 0; i < 30; i += 3) assertEquals("i: " + i, ~i << 8 >> 8, bytes.readInt24()); for (int i = 30; i < 63; i += 3) assertEquals("i: " + i, ~i << 8 >> 8, bytes.readInt24(i)); } @Test public void testReadWriteInt48() { for (long i = 0; i < 30; i += 6) bytes.writeInt48(i, ~i & 0x7FFFFFFFFFFFL); bytes.position(30); for (long i = 30; i < 60; i += 6) bytes.writeInt48(~i & 0x7FFFFFFFFFFFL); assertEquals(60, bytes.position()); bytes.position(0); for (long i = 0; i < 30; i += 6) assertEquals("i: " + i, ~i & 0x7FFFFFFFFFFFL, bytes.readInt48()); for (long i = 30; i < 60; i += 6) assertEquals("i: " + i, ~i & 0x7FFFFFFFFFFFL, bytes.readInt48(i)); // now negative bytes.position(0); for (long i = 0; i < 30; i += 6) bytes.writeInt48(i, ~i); bytes.position(30); for (long i = 30; i < 60; i += 6) bytes.writeInt48(~i); assertEquals(60, bytes.position()); bytes.position(0); for (long i = 0; i < 30; i += 6) assertEquals("i: " + i, ~i << 16 >> 16, bytes.readInt48()); for (long i = 30; i < 60; i += 6) assertEquals("i: " + i, ~i << 16 >> 16, bytes.readInt48(i)); } @Test public void testDateTimes() { long now = System.currentTimeMillis(); bytes.appendDateTimeMillis(now); bytes.append(' '); bytes.appendDateMillis(now); bytes.append('T'); bytes.appendTimeMillis(now % 86400000L); assertEquals(23 * 2 + 1, bytes.position()); bytes.position(0); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); String asStr = sdf.format(new Date(now)); assertEquals(asStr, bytes.parseUTF(SPACE_STOP)); assertEquals(asStr, bytes.parseUTF(SPACE_STOP)); } @Test public void testReadWriteCompactUnsignedShort() { for (int i = 0; i < 64; i += 4) bytes.writeCompactUnsignedShort(i); assertEquals(64 / 4, bytes.position()); bytes.position(0); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readByte(i / 4)); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readCompactUnsignedShort()); } @Test public void testReadWriteCompactUnsignedInt() { for (int i = 0; i < 64; i += 4) bytes.writeCompactUnsignedInt(i); assertEquals(64 / 2, bytes.position()); bytes.position(0); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readShort(i / 2)); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readCompactUnsignedInt()); } @Test public void testReadWriteLong() { for (long i = 0; i < 32; i += 8) bytes.writeLong(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeLong(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readLong()); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readLong(i)); } @Test public void testReadWriteThreadSafeLong() { for (long i = 0; i < 32; i += 8) bytes.writeOrderedLong(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeOrderedLong(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readVolatileLong()); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readVolatileLong(i)); } @Test public void testReadWriteDouble() { for (long i = 0; i < 32; i += 8) bytes.writeDouble(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeDouble(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readDouble(), 0); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readDouble(i), 0); } @Test public void testAppendSubstring() { bytes.append("Hello World", 2, 7).append("\n"); bytes.position(0); assertEquals("Hello World".substring(2, 7), bytes.parseUTF(CONTROL_STOP)); } @Test public void testWriteReadEnum() { bytes.append(BuySell.Buy).append("\t").append(BuySell.Sell); bytes.position(0); assertEquals(BuySell.Buy, bytes.parseEnum(BuySell.class, CONTROL_STOP)); assertEquals(BuySell.Sell, bytes.parseEnum(BuySell.class, CONTROL_STOP)); assertEquals(null, bytes.parseEnum(BuySell.class, CONTROL_STOP)); } @Test public void testAppendParse() { bytes.append(false).append(' '); bytes.append(true).append(' '); bytes.append("what?").append(' '); bytes.append("word£€").append(' '); bytes.append(BuySell.Buy).append(' '); bytes.append(1234).append(' '); bytes.append(123456L).append(' '); bytes.append(1.2345).append(' '); bytes.append(1.5555, 3).append(' '); bytes.position(0); assertEquals(false, bytes.parseBoolean(SPACE_STOP)); assertEquals(true, bytes.parseBoolean(SPACE_STOP)); assertEquals(null, bytes.parseBoolean(SPACE_STOP)); assertEquals("word£€", bytes.parseUTF(SPACE_STOP)); assertEquals(BuySell.Buy, bytes.parseEnum(BuySell.class, SPACE_STOP)); assertEquals(1234, bytes.parseLong()); assertEquals(123456L, bytes.parseLong()); assertEquals(1.2345, bytes.parseDouble(), 0); assertEquals(1.556, bytes.parseDouble(), 0); } @Test public void testWriteByteChar() throws UnsupportedEncodingException { bytes.writeBytes("Hello \u00ff\u01fe\u02fc\n"); bytes.writeChars("Hello \u00ff\u01fe\u02fc\n"); byte[] bytes = new byte[(int) this.bytes.position()]; this.bytes.position(0); this.bytes.readFully(bytes); assertEquals("Hello \u00ff\u00fe\u00fc\n" + "H\u0000e\u0000l\u0000l\u0000o\u0000 \u0000ÿ\u0000þ\u0001ü\u0002\n" + "\u0000", new String(bytes, "ISO-8859-1")); } @Test public void testWriteBytes() { bytes.write("Hello World\n".getBytes(), 0, 10); bytes.write("good bye\n".getBytes(), 4, 4); bytes.write(4, "0 w".getBytes()); bytes.position(0); assertEquals("Hell0 worl bye", bytes.parseUTF(CONTROL_STOP)); } @Test public void testAppendIterable() { bytes.append(Arrays.asList(1, 2, 3, 4, 5), ";").append(' '); bytes.append(new TreeSet(Arrays.asList(21, 2, 13, 4, 5)), ";"); bytes.position(0); assertEquals("1;2;3;4;5 2;4;5;13;21", bytes.parseUTF(CONTROL_STOP)); } @Test public void readWriteMutableDecimal() { Random rand = new Random(2); MutableDecimal md = new MutableDecimal(); MutableDecimal md2 = new MutableDecimal(); // md.set(1260042744, 0); for (int i = 0; i < 20000; i++) { int n = rand.nextInt(); for (int j = 0; j < 6; j++) { testDecimal0(md, md2, n, j); } } } private void testDecimal0(MutableDecimal md, MutableDecimal md2, int n, int j) { md.set(n, j); bytes.position(0); bytes.append(md).append('\n'); bytes.position(0); bytes.parseDecimal(md2); bytes.position(0); String text = bytes.parseUTF(CONTROL_STOP); if (!md.equals(md2)) assertEquals("n: " + n + ", s: " + j + " t: " + text, md, md2); } @Test public void testStream() throws IOException { bytes = new ByteBufferBytes(ByteBuffer.allocateDirect(1000)); GZIPOutputStream out = new GZIPOutputStream(bytes.outputStream()); out.write("Hello world\n".getBytes()); out.close(); bytes.position(0); GZIPInputStream in = new GZIPInputStream(bytes.inputStream()); byte[] bytes = new byte[12]; for (int i = 0; i < 12; i++) bytes[i] = (byte) in.read(); assertEquals(-1, in.read()); assertEquals("Hello world\n", new String(bytes)); in.close(); } @Test public void testStream2() throws IOException { OutputStream out = bytes.outputStream(); out.write(11); out.write(22); out.write(33); out.write(44); out.write(55); bytes.position(0); InputStream in = bytes.inputStream(); assertTrue(in.markSupported()); assertEquals(11, in.read()); in.mark(1); assertEquals(1, bytes.position()); assertEquals(22, in.read()); assertEquals(2, bytes.position()); assertEquals(33, in.read()); in.reset(); assertEquals(1, bytes.position()); assertEquals(22, in.read()); assertEquals(2, in.skip(2)); assertEquals(4, bytes.position()); assertEquals(SIZE - 4, bytes.available()); assertEquals(55, in.read()); in.close(); } @Test public void testWriteObject() { for (Object o : new Object[]{10, 9.9, "string", new Date(), BigDecimal.valueOf(1.1)}) { bytes.position(0); bytes.writeObject(o); // System.out.println(o +" size: "+bytes.position()); assertTrue(bytes.position() < 21); bytes.position(0); Object o2 = bytes.readObject(); bytes.position(0); Object o3 = bytes.readObject(o.getClass()); assertEquals(o, o2); assertEquals(o, o3); } } @Test public void testWriteSerializable() { int capacity = 16 * 1024; byteBuffer = ByteBuffer.allocateDirect(capacity); bytes = new ByteBufferBytes(byteBuffer); Calendar cal = Calendar.getInstance(); bytes.writeObject(cal); Dummy d = new Dummy(); bytes.writeObject(d); bytes.position(0); Calendar cal2 = bytes.readObject(Calendar.class); Dummy d2 = bytes.readObject(Dummy.class); assertEquals(cal, cal2); assertEquals(d, d2); } @Test public void testAddAndGet() { for (int i = 0; i < 10; i++) bytes.addAndGetInt(0L, 10); assertEquals(100, bytes.readInt(0L)); assertEquals(0, bytes.readInt(4L)); for (int i = 0; i < 11; i++) bytes.getAndAdd(4L, 11); assertEquals(100, bytes.readInt(0L)); assertEquals(11 * 11, bytes.readInt(4L)); } enum BuySell { Buy, Sell } static class Dummy implements Serializable { @Override public boolean equals(Object obj) { return obj instanceof Dummy; } } @Test public void testErrors() { int capacity = 1024; byteBuffer = ByteBuffer.allocateDirect(capacity); // it is actually much bigger than it believes bytes = new ByteBufferBytes(byteBuffer, 0, 16); bytes.writeLong(8); assertFalse(bytes.isFinished()); bytes.finish(); assertTrue(bytes.isFinished()); bytes.flush(); bytes.writeLong(16); bytes.finish(); bytes.flush(); try { bytes.writeLong(24); fail(); } catch (IndexOutOfBoundsException expected) { } bytes.finish(); bytes.flush(); bytes.reset(); assertEquals(0, bytes.position()); assertEquals(8, bytes.skip(8)); assertEquals(8, bytes.position()); bytes.writeLong(22); bytes.close(); } @Test public void testWriteList() { List ints = Arrays.asList(1, 2, 3, 4); bytes.writeList(ints); bytes.reset(); List ints2 = new ArrayList(); bytes.readList(ints2, Integer.class); assertEquals(ints, ints2); bytes.reset(); List words = Arrays.asList("Hello word byte for now".split(" ")); bytes.writeList(words); bytes.reset(); List words2 = new ArrayList(); bytes.readList(words2, String.class); } @Test public void testWriteMap() { Map map = new LinkedHashMap() { { put("one", 1); put("two", 2); put("three", 3); put("four", 4); } }; bytes.writeMap(map); bytes.finish(); bytes.reset(); Map map2 = new LinkedHashMap(); bytes.readMap(map2, String.class, Integer.class); assertEquals(map, map2); } @Test public void unloadFailed() throws InterruptedException { bytes.busyLockInt(0); ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("unloadFailed")); Future future = es.submit(new Callable() { @Override public Void call() throws Exception { bytes.unlockInt(0); return null; } }); es.shutdown(); try { future.get(); fail(); } catch (ExecutionException e) { assertEquals(IllegalMonitorStateException.class, e.getCause().getClass()); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/DirectBytesTest.java000077500000000000000000000262211226752375100264170ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.jetbrains.annotations.NotNull; import org.junit.Test; import static org.junit.Assert.*; /** * @author peter.lawrey */ public class DirectBytesTest { @Test public void testSimpleLock() { DirectBytes bytes = new DirectStore(64).createSlice(); bytes.writeLong(0, -1L); assertFalse(bytes.tryLockLong(0)); bytes.writeLong(0, 0L); assertTrue(bytes.tryLockLong(0)); long val1 = bytes.readLong(0); assertTrue(bytes.tryLockLong(0)); bytes.unlockLong(0); assertEquals(val1, bytes.readLong(0)); bytes.unlockLong(0); assertEquals(0L, bytes.readLong(0)); try { bytes.unlockLong(0); fail(); } catch (IllegalMonitorStateException e) { // expected. } } private static void manyToggles(@NotNull DirectStore store1, int lockCount, int from, int to) { long id = Thread.currentThread().getId(); assertEquals(0, id >>> 24); System.out.println("Thread " + id); DirectBytes slice1 = store1.createSlice(); int records = 64; for (int i = 0; i < lockCount; i += records) { for (long j = 0; j < records * 64; j += 64) { slice1.positionAndSize(j, 64); boolean condition = false; for (int k = 0; k < 20; k++) { condition = slice1.tryLockInt(0L) || slice1.tryLockNanosInt(0L, 5 * 1000 * 1000); if (condition) break; if (k > 0) System.out.println("k: " + (5 + k * 5)); } if (!condition) assertTrue("i= " + i, condition); int toggle1 = slice1.readInt(4); if (toggle1 == from) { slice1.writeInt(4L, to); } else { // noinspection AssignmentToForLoopParameter,AssignmentToForLoopParameter i--; } slice1.unlockInt(0L); System.currentTimeMillis(); // small delay } } } private static void manyLongToggles(@NotNull DirectStore store1, int lockCount, int from, int to) { long id = Thread.currentThread().getId(); assertEquals(0, id >>> 32); System.out.println("Thread " + id); DirectBytes slice1 = store1.createSlice(); int records = 64; for (int i = 0; i < lockCount; i += records) { for (long j = 0; j < records * 64; j += 64) { slice1.positionAndSize(j, 64); boolean condition = false; for (int k = 0; k < 20; k++) { condition = slice1.tryLockLong(0L) || slice1.tryLockNanosLong(0L, 5 * 1000 * 1000); if (condition) break; if (k > 0) System.out.println("k: " + (5 + k * 5)); } if (!condition) assertTrue("i= " + i, condition); long toggle1 = slice1.readLong(8); if (toggle1 == from) { slice1.writeLong(8L, to); } else { // noinspection AssignmentToForLoopParameter,AssignmentToForLoopParameter i--; } slice1.unlockLong(0L); System.currentTimeMillis(); // small delay } } } @Test public void testAllocate() throws Exception { long size = 1L << 24; // 31; don't overload cloud-bees DirectStore store = DirectStore.allocate(size); assertEquals(size, store.size()); DirectBytes slice = store.createSlice(); slice.positionAndSize(0, size); slice.writeLong(0, size); slice.writeLong(size - 8, size); store.free(); } @Test public void testLocking() { if (Runtime.getRuntime().availableProcessors() < 2) { System.err.println("Test requires 2 CPUs, skipping"); return; } long start = System.nanoTime(); // a page final DirectStore store1 = DirectStore.allocate(1 << 12); final int lockCount = 10 * 1000 * 1000; new Thread(new Runnable() { @Override public void run() { manyToggles(store1, lockCount, 1, 0); } }).start(); manyToggles(store1, lockCount, 0, 1); store1.free(); long time = System.nanoTime() - start; System.out.printf("Contended lock rate was %,d per second%n", (int) (lockCount * 2 * 1e9 / time)); } @Test public void testLockingLong() { if (Runtime.getRuntime().availableProcessors() < 2) { System.err.println("Test requires 2 CPUs, skipping"); return; } long start = System.nanoTime(); // a page final DirectStore store1 = DirectStore.allocate(1 << 12); final int lockCount = 10 * 1000 * 1000; new Thread(new Runnable() { @Override public void run() { manyLongToggles(store1, lockCount, 1, 0); } }).start(); manyLongToggles(store1, lockCount, 0, 1); store1.free(); long time = System.nanoTime() - start; System.out.printf("Contended lock rate was %,d per second%n", (int) (lockCount * 2 * 1e9 / time)); } @Test public void testLocking2() throws Exception { if (Runtime.getRuntime().availableProcessors() < 2) { System.err.println("Test requires 2 CPUs, skipping"); return; } // a page final DirectStore store1 = DirectStore.allocate(1 << 12); final DirectStore store2 = DirectStore.allocate(1 << 12); final int lockCount = 1000000; Thread t = new Thread(new Runnable() { @Override public void run() { long id = Thread.currentThread().getId(); System.out.println("Thread " + id); assertEquals(0, id >>> 24); int expected = (1 << 24) | (int) id; try { DirectBytes slice1 = store1.createSlice(); DirectBytes slice2 = store2.createSlice(); for (int i = 0; i < lockCount; i += 2) { slice1.busyLockInt(0); slice2.busyLockInt(0); int lockValue1 = slice1.readInt(0); if (lockValue1 != expected) assertEquals(expected, lockValue1); int lockValue2 = slice2.readInt(0); if (lockValue2 != expected) assertEquals(expected, lockValue2); int toggle1 = slice1.readInt(4); if (toggle1 == 1) { slice1.writeInt(4, 0); // if (i % 10000== 0) // System.out.println("t: " + i); } else { // noinspection AssignmentToForLoopParameter i--; } int toggle2 = slice2.readInt(4); if (toggle2 == 1) { slice2.writeInt(4, 0); // if (i % 10000== 0) // System.out.println("t: " + i); } else { // noinspection AssignmentToForLoopParameter i--; } int lockValue1A = slice1.readInt(0); int lockValue2A = slice1.readInt(0); try { slice2.unlockInt(0); slice1.unlockInt(0); } catch (IllegalStateException e) { int lockValue1B = slice1.readInt(0); int lockValue2B = slice2.readInt(0); System.err.println("i= " + i + " lock: " + Integer.toHexString(lockValue1A) + " / " + Integer.toHexString(lockValue2A) + " lock: " + Integer.toHexString(lockValue1B) + " / " + Integer.toHexString(lockValue2B)); throw e; } } } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); long id = Thread.currentThread().getId(); assertEquals(0, id >>> 24); int expected = (1 << 24) | (int) id; System.out.println("Thread " + id); DirectBytes slice1 = store1.createSlice(); DirectBytes slice2 = store2.createSlice(); for (int i = 0; i < lockCount; i += 2) { slice1.busyLockInt(0); slice2.busyLockInt(0); int lockValue1 = slice1.readInt(0); if (lockValue1 != expected) assertEquals(expected, lockValue1); int lockValue2 = slice2.readInt(0); if (lockValue2 != expected) assertEquals(expected, lockValue2); int toggle1 = slice1.readInt(4); if (toggle1 == 0) { slice1.writeInt(4, 1); // if (i % 10000== 0) // System.out.println("t: " + i); } else { // noinspection AssignmentToForLoopParameter i--; } int toggle2 = slice2.readInt(4); if (toggle2 == 0) { slice2.writeInt(4, 1); // if (i % 10000== 0) // System.out.println("t: " + i); } else { // noinspection AssignmentToForLoopParameter i--; } int lockValue1A = slice1.readInt(0); int lockValue2A = slice1.readInt(0); try { slice2.unlockInt(0); slice1.unlockInt(0); } catch (IllegalStateException e) { int lockValue1B = slice1.readInt(0); int lockValue2B = slice2.readInt(0); System.err.println("i= " + i + " lock: " + Integer.toHexString(lockValue1A) + " / " + Integer.toHexString(lockValue2A) + " lock: " + Integer.toHexString(lockValue1B) + " / " + Integer.toHexString(lockValue2B)); throw e; } } store1.free(); store2.free(); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/IOToolsTest.java000066400000000000000000000023571226752375100255270ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.junit.Test; import java.io.Closeable; import java.io.IOException; import java.util.Arrays; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey * Date: 20/09/13 * Time: 09:54 */ public class IOToolsTest { @Test public void testClose() { final int[] count = {0}; Closeable c = new Closeable() { @Override public void close() throws IOException { count[0]++; } }; IOTools.close(c); assertEquals(1, count[0]); IOTools.close(Arrays.asList(c, c, c)); assertEquals(4, count[0]); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/LockingViaFileLockMain.java000066400000000000000000000071221226752375100275760ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; /** * User: peter * Date: 22/12/13 * Time: 11:05 * * Toggled 10,000,128 times with an average delay of 2,402 ns */ public class LockingViaFileLockMain { static int RECORDS = Integer.getInteger("records", 128); static int RECORD_SIZE = Integer.getInteger("record_size", 64); // cache line size static int WARMUP = Integer.getInteger("warmup", RECORDS * 100); static int RUNS = Integer.getInteger("runs", 5 * 1000 * 1000); // offsets // static int LOCK = 0; static int FLAG = 8; public static void main(String... args) throws IOException, InterruptedException { boolean toggleTo = Boolean.parseBoolean(args[0]); File tmpFile = new File(System.getProperty("java.io.tmpdir"), "lock-test.dat"); FileChannel fc = new RandomAccessFile(tmpFile, "rw").getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, RECORDS * RECORD_SIZE); ByteBufferBytes bytes = new ByteBufferBytes(mbb.order(ByteOrder.nativeOrder())); long start = 0; for (int i = -WARMUP / RECORDS; i < (RUNS + RECORDS - 1) / RECORDS; i++) { if (i == 0) { start = System.nanoTime(); System.out.println("Started"); } for (int j = 0; j < RECORDS; j++) { int recordOffset = j * RECORD_SIZE; for (int t = 9999; t >= 0; t--) { if (t == 0) if (i >= 0) { throw new AssertionError("Didn't toggle in time !??"); } else { System.out.println("waiting"); t = 99999; Thread.sleep(200); } final FileLock lock = fc.lock(); try { bytes.readBarrier(); boolean flag = bytes.readBoolean(recordOffset + FLAG); if (flag == toggleTo) { if (t % 100 == 0) System.out.println("j: " + j + " is " + flag); continue; } bytes.writeBoolean(recordOffset + FLAG, toggleTo); bytes.writeBarrier(); break; } finally { lock.release(); } } } } long time = System.nanoTime() - start; final int toggles = (RUNS + RECORDS - 1) / RECORDS * RECORDS * 2; // one for each of two processes. System.out.printf("Toggled %,d times with an average delay of %,d ns%n", toggles, time / toggles); fc.close(); tmpFile.deleteOnExit(); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/LockingViaMMapMain.java000066400000000000000000000073651226752375100267510ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; /** * User: peter * Date: 22/12/13 * Time: 11:05 * * Toggled 10,000,128 times with an average delay of 28 ns */ public class LockingViaMMapMain { static int RECORDS = Integer.getInteger("records", 128); static int RECORD_SIZE = Integer.getInteger("record_size", 64); // cache line size static int WARMUP = Integer.getInteger("warmup", RECORDS * 100); static int RUNS = Integer.getInteger("runs", 5 * 1000 * 1000); // offsets static int LOCK = 0; static int FLAG = 8; static int LENGTH = 16; public static void main(String... args) throws IOException, InterruptedException { boolean toggleTo = Boolean.parseBoolean(args[0]); File tmpFile = new File(System.getProperty("java.io.tmpdir"), "lock-test.dat"); FileChannel fc = new RandomAccessFile(tmpFile, "rw").getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, RECORDS * RECORD_SIZE); ByteBufferBytes bytes = new ByteBufferBytes(mbb.order(ByteOrder.nativeOrder())); bytes.setCurrentThread(); long start = 0; for (int i = -WARMUP / RECORDS; i < (RUNS + RECORDS - 1) / RECORDS; i++) { if (i == 0) { start = System.nanoTime(); System.out.println("Started"); } for (int j = 0; j < RECORDS; j++) { int recordOffset = j * RECORD_SIZE; for (int t = 1; t < 10000; t++) { if (t == 0) if (i >= 0) { throw new AssertionError("Didn't toggle in time !??"); } else { Thread.sleep(200); } bytes.busyLockLong(recordOffset + LOCK); try { boolean flag = bytes.readBoolean(recordOffset + FLAG); if (flag != toggleTo) { bytes.writeBoolean(recordOffset + FLAG, toggleTo); break; } } finally { bytes.unlockLong(recordOffset + LOCK); } if (t % 100 == 0) System.out.println("waiting for " + j + " pid " + (int) bytes.readLong(recordOffset + LOCK) + " is " + bytes.readBoolean(recordOffset + FLAG)); if (t > 100) if (t > 200) Thread.sleep(1); else Thread.yield(); } } } long time = System.nanoTime() - start; final int toggles = (RUNS + RECORDS - 1) / RECORDS * RECORDS * 2; // one for each of two processes. System.out.printf("Toggled %,d times with an average delay of %,d ns%n", toggles, time / toggles); fc.close(); tmpFile.deleteOnExit(); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/MappedFileTest.java000066400000000000000000000061461226752375100262050ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.junit.Test; import java.io.*; import java.nio.MappedByteBuffer; import static org.junit.Assert.assertTrue; public class MappedFileTest { public static void printMappings() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/self/maps"))); try { for (String line; (line = br.readLine()) != null; ) { System.out.println(line); } } catch (IOException ioe) { br.close(); throw ioe; } } public static void delete(File file) throws IOException { if (file.delete() || !file.exists()) return; // get an error message as to why. ProcessBuilder pb = new ProcessBuilder("/bin/rm", file.getAbsolutePath()); pb.redirectErrorStream(true); Process p = pb.start(); StringWriter sw = new StringWriter(); char[] chars = new char[512]; Reader r = new InputStreamReader(p.getInputStream()); for (int len; (len = r.read(chars)) > 0; ) sw.write(chars, 0, len); String msg = sw.toString().trim(); if (msg.length() > 0) throw new IOException(msg); } @Test public void testUnmap() throws IOException, InterruptedException { String TMP = System.getProperty("java.io.tmpdir"); String basePath = TMP + "/testUnmap"; File file = new File(basePath); File dir = file.getParentFile(); long free0 = dir.getFreeSpace(); MappedFile mfile = new MappedFile(basePath, 1024 * 1024); MappedMemory map0 = mfile.acquire(0); fill(map0.buffer()); MappedMemory map1 = mfile.acquire(1); fill(map1.buffer().force()); long free1 = dir.getFreeSpace(); map1.release(); map0.release(); mfile.close(); // printMappings(); long free2 = dir.getFreeSpace(); delete(file); long free3 = 0; for (int i = 0; i < 100; i++) { free3 = dir.getFreeSpace(); System.out.println("Freed " + free0 + " ~ " + free1 + " ~ " + free2 + " ~ " + free3 + ", delete = " + file.delete()); if (free3 > free1) break; Thread.sleep(500); } assertTrue("free3-free1: " + (free3 - free1), free3 > free1); } private void fill(MappedByteBuffer buffer) { buffer.position(0); while (buffer.remaining() >= 8) buffer.putLong(0x123456789ABCDEFL); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/MutableDecimalTest.java000066400000000000000000000034451226752375100270460ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import org.junit.Test; import static org.junit.Assert.*; /** * User: peter.lawrey * Date: 20/09/13 * Time: 10:40 */ public class MutableDecimalTest { @Test public void testConstructor() { MutableDecimal md = new MutableDecimal(Long.MAX_VALUE); assertEquals(Long.MAX_VALUE, md.longValue()); assertEquals("" + Long.MAX_VALUE, md.toString()); MutableDecimal md2 = new MutableDecimal(Long.MAX_VALUE, 10); assertEquals(Long.MAX_VALUE / 1e10, md2.doubleValue(), 0); assertEquals("922337203.6854775807", md2.toString()); MutableDecimal md3 = new MutableDecimal(Math.PI, 6); assertEquals(3.141593, md3.doubleValue(), 0); assertEquals(3.141593f, md3.floatValue(), 0); assertEquals(3, md3.intValue()); assertEquals("3.141593", md3.toString()); assertEquals(1, md.compareTo(md2)); assertEquals(-1, md2.compareTo(md)); assertEquals(1, md2.compareTo(md3)); assertEquals(-1, md3.compareTo(md2)); assertEquals(3141593, md3.value()); assertEquals(6, md3.scale()); assertTrue(md3.isSet()); md3.clear(); assertFalse(md3.isSet()); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/NativeBytesTest.java000066400000000000000000000744001226752375100264320ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io; import net.openhft.lang.Maths; import net.openhft.lang.thread.NamedThreadFactory; import org.junit.Before; import org.junit.Test; import sun.nio.ch.DirectBuffer; import java.io.*; import java.math.BigDecimal; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.*; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import static net.openhft.lang.io.StopCharTesters.CONTROL_STOP; import static net.openhft.lang.io.StopCharTesters.SPACE_STOP; import static org.junit.Assert.*; /** * Created with IntelliJ IDEA. User: peter.lawrey Date: 17/09/13 Time: 16:09 To change this template use File | Settings | File * Templates. */ public class NativeBytesTest { public static final int SIZE = 128; private NativeBytes bytes; private ByteBuffer byteBuffer; @Before public void beforeTest() { byteBuffer = ByteBuffer.allocateDirect(SIZE); long addr = ((DirectBuffer) byteBuffer).address(); bytes = new NativeBytes(addr, addr, addr + SIZE); } @Test public void testLongHash() throws Exception { byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8}; long h = NativeBytes.longHash(bytes, 0, bytes.length); assertFalse(h == 0); byte[] bytes2 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; long h2 = NativeBytes.longHash(bytes2, 0, bytes2.length); assertFalse(h2 == 0); assertFalse(h2 == h); } @Test public void testRead() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.writeByte(i, i); bytes.position(0); for (int i = 0; i < bytes.capacity(); i++) assertEquals((byte) i, bytes.read()); for (int i = (int) (bytes.capacity() - 1); i >= 0; i--) { assertEquals((byte) i, bytes.readByte(i)); } } @Test public void testReadFully() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.write(i); bytes.position(0); byte[] bytes = new byte[(int) this.bytes.capacity()]; this.bytes.readFully(bytes); for (int i = 0; i < this.bytes.capacity(); i++) assertEquals((byte) i, bytes[i]); } @Test public void testCompareAndSetLong() throws Exception { assertTrue(bytes.compareAndSwapLong(0, 0, 1)); assertFalse(bytes.compareAndSwapLong(0, 0, 1)); assertTrue(bytes.compareAndSwapLong(8, 0, 1)); assertTrue(bytes.compareAndSwapLong(0, 1, 2)); } @Test public void testPosition() throws Exception { for (int i = 0; i < bytes.capacity(); i++) bytes.write(i); for (int i = (int) (bytes.capacity() - 1); i >= 0; i--) { bytes.position(i); assertEquals((byte) i, bytes.read()); } } @Test public void testCapacity() throws Exception { assertEquals(SIZE, bytes.capacity()); assertEquals(10, new NativeBytes(0, 0, 10).capacity()); } @Test public void testRemaining() throws Exception { assertEquals(SIZE, bytes.remaining()); bytes.position(10); assertEquals(SIZE - 10, bytes.remaining()); } @Test public void testByteOrder() throws Exception { assertEquals(ByteOrder.nativeOrder(), bytes.byteOrder()); } @Test public void testCheckEndOfBuffer() throws Exception { bytes.checkEndOfBuffer(); bytes.position(SIZE + 2); try { bytes.checkEndOfBuffer(); fail(); } catch (IndexOutOfBoundsException expected) { } } @Test public void testAppendDouble() { testAppendDouble0(-6.895305375646115E24); Random random = new Random(1); for (int i = 0; i < 100000; i++) { double d = Math.pow(1e32, random.nextDouble()) / 1e6; if (i % 3 == 0) d = -d; testAppendDouble0(d); } } private void testAppendDouble0(double d) { bytes.position(0); bytes.append(d).append(' '); bytes.position(0); double d2 = bytes.parseDouble(); assertEquals(d, d2, 0); } @Test public void testAppendDouble2() { // testAppendDouble0(-0.93879148954440506, 14); // testAppendDouble0(-0.214980202661, 12); // testAppendDouble0(-0.937082148896, 12); testAppendDouble0(0.17805, 5); Random random = new Random(1); for (int j = 0; j < 20000; j++) { double d = random.nextDouble(); if (j % 3 == 0) d = -d; // if (j % 5 == 0) d *= 1e6; for (int i = 0; i < 4; i++) { testAppendDouble0(d, i); } } } private void testAppendDouble0(double d, int precision) { bytes.position(0); bytes.append(d, precision).append(' '); bytes.position(0); String text = bytes.parseUTF(SPACE_STOP); bytes.position(0); assertEquals(0, bytes.position()); double d2 = bytes.parseDouble(); double d3 = (double) Math.round(d * Maths.power10(precision)) / Maths.power10(precision); // if (precision >= 14) // assertEquals("'" + text + "' p: " + precision + " v: " + new BigDecimal(d), d3, d2, 5e-29 * Maths.power10(precision)); // else assertEquals("'" + text + "' p: " + precision, d3, d2, 0); } @Test public void testWriteReadBytes() { byte[] bytes = "Hello World!".getBytes(); this.bytes.write(bytes); byte[] bytes2 = new byte[bytes.length]; this.bytes.position(0); this.bytes.read(bytes2); assertTrue(Arrays.equals(bytes, bytes2)); this.bytes.write(22, bytes); byte[] bytes3 = new byte[bytes.length]; this.bytes.skipBytes((int) (22 - this.bytes.position())); assertEquals(bytes3.length, this.bytes.read(bytes3)); assertTrue(Arrays.equals(bytes, bytes3)); this.bytes.position(this.bytes.capacity()); assertEquals(-1, this.bytes.read(bytes3)); } @Test public void testWriteReadUTFΔ() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.writeUTFΔ(word); } bytes.writeUTFΔ(null); bytes.position(0); for (String word : words) { assertEquals(word, bytes.readUTFΔ()); } assertEquals(null, bytes.readUTFΔ()); assertEquals("", bytes.readUTFΔ()); assertEquals(26, bytes.position()); // check the size bytes.position(0); StringBuilder sb = new StringBuilder(); for (String word : words) { assertTrue(bytes.readUTFΔ(sb)); assertEquals(word, sb.toString()); } assertFalse(bytes.readUTFΔ(sb)); assertTrue(bytes.readUTFΔ(sb)); assertEquals("", sb.toString()); } @Test public void testWriteReadUTF() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.writeUTF(word); } bytes.writeUTF(""); assertEquals(28, bytes.position()); // check the size, more bytes for less strings than writeUTFΔ bytes.position(0); for (String word : words) { assertEquals(word, bytes.readUTF()); } assertEquals("", bytes.readUTF()); } @Test public void testAppendParseUTF() { String[] words = "Hello,World!,Bye£€!".split(","); for (String word : words) { bytes.append(word).append('\t'); } bytes.append('\t'); bytes.position(0); for (String word : words) { assertEquals(word, bytes.parseUTF(CONTROL_STOP)); } assertEquals("", bytes.parseUTF(CONTROL_STOP)); bytes.position(0); StringBuilder sb = new StringBuilder(); for (String word : words) { bytes.parseUTF(sb, CONTROL_STOP); assertEquals(word, sb.toString()); } bytes.parseUTF(sb, CONTROL_STOP); assertEquals("", sb.toString()); bytes.position(0); bytes.skipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(13, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(17, bytes.position()); bytes.skipTo(CONTROL_STOP); assertEquals(18, bytes.position()); bytes.position(0); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(6, bytes.position()); bytes.position(10); bytes.stepBackAndSkipTo(CONTROL_STOP); assertEquals(13, bytes.position()); } @Test public void testWriteReadLines() { byte[] bytes = "Hello\nWorld!\r\nBye".getBytes(); this.bytes.write(bytes); this.bytes.position(0); assertEquals("Hello", this.bytes.readLine()); assertEquals("World!", this.bytes.readLine()); assertTrue(this.bytes.readLine().startsWith("Bye")); } @Test public void testWriteReadByteBuffer() { byte[] bytes = "Hello\nWorld!\r\nBye".getBytes(); this.bytes.write(ByteBuffer.wrap(bytes)); this.bytes.position(0); byte[] bytes2 = new byte[bytes.length + 1]; ByteBuffer bb2 = ByteBuffer.wrap(bytes2); this.bytes.read(bb2); assertEquals(bytes2.length, bb2.position()); assertTrue(Arrays.equals(bytes, Arrays.copyOf(bytes2, bytes.length))); } @Test public void testReadWriteBoolean() { for (int i = 0; i < 32; i++) bytes.writeBoolean(i, (i & 3) == 0); bytes.position(32); for (int i = 32; i < 64; i++) bytes.writeBoolean((i & 5) == 0); bytes.position(0); for (int i = 0; i < 32; i++) assertEquals((i & 3) == 0, bytes.readBoolean()); for (int i = 32; i < 64; i++) assertEquals((i & 5) == 0, bytes.readBoolean(i)); } @Test public void testReadWriteShort() { for (int i = 0; i < 32; i += 2) bytes.writeShort(i, i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeShort(i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(i, bytes.readShort()); for (int i = 32; i < 64; i += 2) assertEquals(i, bytes.readShort(i)); } @Test public void testReadWriteCompactShort() { int[] ints = {Short.MIN_VALUE, Short.MAX_VALUE, -125, 0, 127, -10000, 10000}; for (int i : ints) { bytes.writeCompactShort(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 + 2 * 3, bytes.position()); bytes.position(0); for (int i : ints) assertEquals(i, bytes.readCompactShort()); } @Test public void testReadWriteCompactInt() { int[] ints = {-10000000, Integer.MIN_VALUE, Integer.MAX_VALUE, Short.MIN_VALUE + 3, 0, Short.MAX_VALUE, 10000000}; for (int i : ints) { bytes.writeCompactInt(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 * 2 + 2 * 6, bytes.position()); bytes.position(0); for (int i : ints) assertEquals(i, bytes.readCompactInt()); } @Test public void testReadWriteCompactLong() { long[] ints = {Long.MAX_VALUE, -100000000000L, Long.MIN_VALUE, Integer.MIN_VALUE + 3, 0, Integer.MAX_VALUE, 100000000000L}; for (long i : ints) { bytes.writeCompactLong(i); // System.out.println(i + " " + bytes.position()); } assertEquals(5 * 4 + 2 * 12, bytes.position()); bytes.position(0); for (long i : ints) assertEquals(i, bytes.readCompactLong()); } @Test public void testReadWriteCompactDouble() { double[] doubles = {1, 1000, 1000000, -100000000, 0.1f, 0.1, 0.5, 0.51}; for (double i : doubles) { bytes.writeCompactDouble(i); // System.out.println(i + " " + bytes.position()); } assertEquals(6 * 4 + 2 * 12, bytes.position()); bytes.position(0); for (double i : doubles) assertEquals(i, bytes.readCompactDouble(), 0.0); } @Test public void testReadWriteStop() { long[] longs = {Long.MIN_VALUE, Long.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE}; for (long i : longs) { bytes.writeStopBit(i); // System.out.println(i + " " + bytes.position()); } assertEquals(9 + 10, +5 + 6, bytes.position()); bytes.position(0); for (long i : longs) assertEquals(i, bytes.readStopBit()); } @Test public void testReadWriteChar() { for (int i = 0; i < 32; i += 2) bytes.writeChar(i, i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeChar(i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(i, bytes.readChar()); for (int i = 32; i < 64; i += 2) assertEquals(i, bytes.readChar(i)); } @Test public void testReadWriteUnsignedShort() { for (int i = 0; i < 32; i += 2) bytes.writeUnsignedShort(i, ~i); bytes.position(32); for (int i = 32; i < 64; i += 2) bytes.writeUnsignedShort(~i); bytes.position(0); for (int i = 0; i < 32; i += 2) assertEquals(~i & 0xFFFF, bytes.readUnsignedShort()); for (int i = 32; i < 64; i += 2) assertEquals(~i & 0xFFFF, bytes.readUnsignedShort(i)); } @Test public void testReadWriteInt() { for (int i = 0; i < 32; i += 4) bytes.writeInt(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeInt(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readInt()); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readInt(i)); } @Test public void testReadWriteThreadeSafeInt() { for (int i = 0; i < 32; i += 4) bytes.writeOrderedInt(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeOrderedInt(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readVolatileInt()); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readVolatileInt(i)); } @Test public void testReadWriteFloat() { for (int i = 0; i < 32; i += 4) bytes.writeFloat(i, i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeFloat(i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(i, bytes.readFloat(), 0); for (int i = 32; i < 64; i += 4) assertEquals(i, bytes.readFloat(i), 0); } @Test public void testReadWriteUnsignedInt() { for (int i = 0; i < 32; i += 4) bytes.writeUnsignedInt(i, ~i); bytes.position(32); for (int i = 32; i < 64; i += 4) bytes.writeUnsignedInt(~i); bytes.position(0); for (int i = 0; i < 32; i += 4) assertEquals(~i & 0xFFFFFFFFL, bytes.readUnsignedInt()); for (int i = 32; i < 64; i += 4) assertEquals(~i & 0xFFFFFFFFL, bytes.readUnsignedInt(i)); } @Test public void testReadWriteInt24() { for (int i = 0; i < 30; i += 3) bytes.writeInt24(i, ~i & 0x7FFFFF); bytes.position(30); for (int i = 30; i < 63; i += 3) bytes.writeInt24(~i & 0x7FFFFF); assertEquals(63, bytes.position()); bytes.position(0); for (int i = 0; i < 30; i += 3) assertEquals("i: " + i, ~i & 0x7FFFFFL, bytes.readInt24()); for (int i = 30; i < 63; i += 3) assertEquals("i: " + i, ~i & 0x7FFFFFL, bytes.readInt24(i)); // now negative bytes.position(0); for (int i = 0; i < 30; i += 3) bytes.writeInt24(i, ~i); bytes.position(30); for (int i = 30; i < 63; i += 3) bytes.writeInt24(~i); assertEquals(63, bytes.position()); bytes.position(0); for (int i = 0; i < 30; i += 3) assertEquals("i: " + i, ~i << 8 >> 8, bytes.readInt24()); for (int i = 30; i < 63; i += 3) assertEquals("i: " + i, ~i << 8 >> 8, bytes.readInt24(i)); } @Test public void testReadWriteInt48() { for (long i = 0; i < 30; i += 6) bytes.writeInt48(i, ~i & 0x7FFFFFFFFFFFL); bytes.position(30); for (long i = 30; i < 60; i += 6) bytes.writeInt48(~i & 0x7FFFFFFFFFFFL); assertEquals(60, bytes.position()); bytes.position(0); for (long i = 0; i < 30; i += 6) assertEquals("i: " + i, ~i & 0x7FFFFFFFFFFFL, bytes.readInt48()); for (long i = 30; i < 60; i += 6) assertEquals("i: " + i, ~i & 0x7FFFFFFFFFFFL, bytes.readInt48(i)); // now negative bytes.position(0); for (long i = 0; i < 30; i += 6) bytes.writeInt48(i, ~i); bytes.position(30); for (long i = 30; i < 60; i += 6) bytes.writeInt48(~i); assertEquals(60, bytes.position()); bytes.position(0); for (long i = 0; i < 30; i += 6) assertEquals("i: " + i, ~i << 16 >> 16, bytes.readInt48()); for (long i = 30; i < 60; i += 6) assertEquals("i: " + i, ~i << 16 >> 16, bytes.readInt48(i)); } @Test public void testDateTimes() { long now = System.currentTimeMillis(); bytes.appendDateTimeMillis(now); bytes.append(' '); bytes.appendDateMillis(now); bytes.append('T'); bytes.appendTimeMillis(now % 86400000L); assertEquals(23 * 2 + 1, bytes.position()); bytes.position(0); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd'T'HH:mm:ss.SSS"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); String asStr = sdf.format(new Date(now)); assertEquals(asStr, bytes.parseUTF(SPACE_STOP)); assertEquals(asStr, bytes.parseUTF(SPACE_STOP)); } @Test public void testReadWriteCompactUnsignedShort() { for (int i = 0; i < 64; i += 4) bytes.writeCompactUnsignedShort(i); assertEquals(64 / 4, bytes.position()); bytes.position(0); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readByte(i / 4)); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readCompactUnsignedShort()); } @Test public void testReadWriteCompactUnsignedInt() { for (int i = 0; i < 64; i += 4) bytes.writeCompactUnsignedInt(i); assertEquals(64 / 2, bytes.position()); bytes.position(0); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readShort(i / 2)); for (int i = 0; i < 64; i += 4) assertEquals(i, bytes.readCompactUnsignedInt()); } @Test public void testReadWriteLong() { for (long i = 0; i < 32; i += 8) bytes.writeLong(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeLong(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readLong()); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readLong(i)); } @Test public void testReadWriteThreadSafeLong() { for (long i = 0; i < 32; i += 8) bytes.writeOrderedLong(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeOrderedLong(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readVolatileLong()); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readVolatileLong(i)); } @Test public void testReadWriteDouble() { for (long i = 0; i < 32; i += 8) bytes.writeDouble(i, i); bytes.position(32); for (long i = 32; i < 64; i += 8) bytes.writeDouble(i); bytes.position(0); for (long i = 0; i < 32; i += 8) assertEquals(i, bytes.readDouble(), 0); for (long i = 32; i < 64; i += 8) assertEquals(i, bytes.readDouble(i), 0); } @Test public void testAppendSubstring() { bytes.append("Hello World", 2, 7).append("\n"); bytes.position(0); assertEquals("Hello World".substring(2, 7), bytes.parseUTF(CONTROL_STOP)); } @Test public void testWriteReadEnum() { bytes.append(BuySell.Buy).append("\t").append(BuySell.Sell); bytes.position(0); assertEquals(BuySell.Buy, bytes.parseEnum(BuySell.class, CONTROL_STOP)); assertEquals(BuySell.Sell, bytes.parseEnum(BuySell.class, CONTROL_STOP)); assertEquals(null, bytes.parseEnum(BuySell.class, CONTROL_STOP)); } @Test public void testAppendParse() { bytes.append(false).append(' '); bytes.append(true).append(' '); bytes.append("what?").append(' '); bytes.append("word£€").append(' '); bytes.append(BuySell.Buy).append(' '); bytes.append(1234).append(' '); bytes.append(123456L).append(' '); bytes.append(1.2345).append(' '); bytes.append(1.5555, 3).append(' '); bytes.position(0); assertEquals(false, bytes.parseBoolean(SPACE_STOP)); assertEquals(true, bytes.parseBoolean(SPACE_STOP)); assertEquals(null, bytes.parseBoolean(SPACE_STOP)); assertEquals("word£€", bytes.parseUTF(SPACE_STOP)); assertEquals(BuySell.Buy, bytes.parseEnum(BuySell.class, SPACE_STOP)); assertEquals(1234, bytes.parseLong()); assertEquals(123456L, bytes.parseLong()); assertEquals(1.2345, bytes.parseDouble(), 0); assertEquals(1.556, bytes.parseDouble(), 0); } @Test public void testWriteByteChar() throws UnsupportedEncodingException { bytes.writeBytes("Hello \u00ff\u01fe\u02fc\n"); bytes.writeChars("Hello \u00ff\u01fe\u02fc\n"); byte[] bytes = new byte[(int) this.bytes.position()]; this.bytes.position(0); this.bytes.readFully(bytes); assertEquals("Hello \u00ff\u00fe\u00fc\n" + "H\u0000e\u0000l\u0000l\u0000o\u0000 \u0000ÿ\u0000þ\u0001ü\u0002\n" + "\u0000", new String(bytes, "ISO-8859-1")); } @Test public void testWriteBytes() { bytes.write("Hello World\n".getBytes(), 0, 10); bytes.write("good bye\n".getBytes(), 4, 4); bytes.write(4, "0 w".getBytes()); bytes.position(0); assertEquals("Hell0 worl bye", bytes.parseUTF(CONTROL_STOP)); } @Test public void testAppendIterable() { bytes.append(Arrays.asList(1, 2, 3, 4, 5), ";").append(' '); bytes.append(new TreeSet(Arrays.asList(21, 2, 13, 4, 5)), ";"); bytes.position(0); assertEquals("1;2;3;4;5 2;4;5;13;21", bytes.parseUTF(CONTROL_STOP)); } @Test public void readWriteMutableDecimal() { Random rand = new Random(2); MutableDecimal md = new MutableDecimal(); MutableDecimal md2 = new MutableDecimal(); // md.set(1260042744, 0); for (int i = 0; i < 20000; i++) { int n = rand.nextInt(); for (int j = 0; j < 6; j++) { testDecimal0(md, md2, n, j); } } } private void testDecimal0(MutableDecimal md, MutableDecimal md2, int n, int j) { md.set(n, j); bytes.position(0); bytes.append(md).append('\n'); bytes.position(0); bytes.parseDecimal(md2); bytes.position(0); String text = bytes.parseUTF(CONTROL_STOP); if (!md.equals(md2)) assertEquals("n: " + n + ", s: " + j + " t: " + text, md, md2); } @Test public void testStream() throws IOException { GZIPOutputStream out = new GZIPOutputStream(bytes.outputStream()); out.write("Hello world\n".getBytes()); out.close(); bytes.position(0); GZIPInputStream in = new GZIPInputStream(bytes.inputStream()); byte[] bytes = new byte[12]; for (int i = 0; i < 12; i++) bytes[i] = (byte) in.read(); assertEquals(-1, in.read()); assertEquals("Hello world\n", new String(bytes)); in.close(); } @Test public void testStream2() throws IOException { OutputStream out = bytes.outputStream(); out.write(11); out.write(22); out.write(33); out.write(44); out.write(55); bytes.position(0); InputStream in = bytes.inputStream(); assertTrue(in.markSupported()); assertEquals(11, in.read()); in.mark(1); assertEquals(1, bytes.position()); assertEquals(22, in.read()); assertEquals(2, bytes.position()); assertEquals(33, in.read()); in.reset(); assertEquals(1, bytes.position()); assertEquals(22, in.read()); assertEquals(2, in.skip(2)); assertEquals(4, bytes.position()); assertEquals(SIZE - 4, bytes.available()); assertEquals(55, in.read()); in.close(); } @Test public void testWriteObject() { for (Object o : new Object[]{10, 9.9, "string", new Date(), BigDecimal.valueOf(1.1)}) { bytes.position(0); bytes.writeObject(o); // System.out.println(o +" size: "+bytes.position()); assertTrue(bytes.position() < 21); bytes.position(0); Object o2 = bytes.readObject(); bytes.position(0); Object o3 = bytes.readObject(o.getClass()); assertEquals(o, o2); assertEquals(o, o3); } } @Test public void testWriteSerializable() { int capacity = 16 * 1024; byteBuffer = ByteBuffer.allocateDirect(capacity); long addr = ((DirectBuffer) byteBuffer).address(); bytes = new NativeBytes(addr, addr, addr + capacity); Calendar cal = Calendar.getInstance(); bytes.writeObject(cal); Dummy d = new Dummy(); bytes.writeObject(d); bytes.position(0); Calendar cal2 = bytes.readObject(Calendar.class); Dummy d2 = bytes.readObject(Dummy.class); assertEquals(cal, cal2); assertEquals(d, d2); } @Test public void testAddAndGet() { for (int i = 0; i < 10; i++) bytes.addAndGetInt(0L, 10); assertEquals(100, bytes.readInt(0L)); assertEquals(0, bytes.readInt(4L)); for (int i = 0; i < 11; i++) bytes.getAndAdd(4L, 11); assertEquals(100, bytes.readInt(0L)); assertEquals(11 * 11, bytes.readInt(4L)); } enum BuySell { Buy, Sell } static class Dummy implements Serializable { @Override public boolean equals(Object obj) { return obj instanceof Dummy; } } @Test public void testErrors() { int capacity = 1024; byteBuffer = ByteBuffer.allocateDirect(capacity); long addr = ((DirectBuffer) byteBuffer).address(); // it is actually much bigger than it believes bytes = new NativeBytes(addr, addr, addr + 16); bytes.writeLong(8); assertFalse(bytes.isFinished()); bytes.finish(); assertTrue(bytes.isFinished()); bytes.flush(); bytes.writeLong(16); bytes.finish(); bytes.flush(); bytes.writeLong(24); try { bytes.finish(); fail(); } catch (IndexOutOfBoundsException expected) { } try { bytes.flush(); fail(); } catch (IndexOutOfBoundsException expected) { } bytes.reset(); assertEquals(0, bytes.position()); assertEquals(8, bytes.skip(8)); assertEquals(8, bytes.position()); bytes.writeLong(22); bytes.close(); } @Test public void testWriteList() { List ints = Arrays.asList(1, 2, 3, 4); bytes.writeList(ints); bytes.reset(); List ints2 = new ArrayList(); bytes.readList(ints2, Integer.class); assertEquals(ints, ints2); bytes.reset(); List words = Arrays.asList("Hello word byte for now".split(" ")); bytes.writeList(words); bytes.reset(); List words2 = new ArrayList(); bytes.readList(words2, String.class); } @Test public void testWriteMap() { Map map = new LinkedHashMap() { { put("one", 1); put("two", 2); put("three", 3); put("four", 4); } }; bytes.writeMap(map); bytes.finish(); bytes.reset(); Map map2 = new LinkedHashMap(); bytes.readMap(map2, String.class, Integer.class); assertEquals(map, map2); } @Test public void unloadFailed() throws InterruptedException { bytes.busyLockInt(0); ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("unloadFailed")); Future future = es.submit(new Callable() { @Override public Void call() throws Exception { bytes.unlockInt(0); return null; } }); es.shutdown(); try { future.get(); fail(); } catch (ExecutionException e) { assertEquals(IllegalMonitorStateException.class, e.getCause().getClass()); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/examples/000077500000000000000000000000001226752375100243035ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/examples/ParserExampleMain.java000066400000000000000000000041441226752375100305260ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.examples; import net.openhft.lang.io.ByteBufferBytes; import net.openhft.lang.io.StopCharTesters; import java.nio.ByteBuffer; import static org.junit.Assert.assertEquals; /** * Run with -verbosegc -Xmx32m *

* Average time was 282 nano-seconds */ public class ParserExampleMain { public static void main(String... ignored) { ByteBuffer wrap = ByteBuffer.allocate(1024); ByteBufferBytes bufferBytes = new ByteBufferBytes(wrap); byte[] bytes = "BAC,12.32,12.54,12.56,232443".getBytes(); int runs = 10000000; long start = System.nanoTime(); for (int i = 0; i < runs; i++) { bufferBytes.reset(); // read the next message. bufferBytes.write(bytes); bufferBytes.position(0); // decode message String word = bufferBytes.parseUTF(StopCharTesters.COMMA_STOP); double low = bufferBytes.parseDouble(); double curr = bufferBytes.parseDouble(); double high = bufferBytes.parseDouble(); long sequence = bufferBytes.parseLong(); if (i == 0) { assertEquals("BAC", word); assertEquals(12.32, low, 0.0); assertEquals(12.54, curr, 0.0); assertEquals(12.56, high, 0.0); assertEquals(232443, sequence); } } long time = System.nanoTime() - start; System.out.println("Average time was " + time / runs + " nano-seconds"); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/000077500000000000000000000000001226752375100253425ustar00rootroot00000000000000ByteMarshallableMarshallerTest.java000066400000000000000000000045051226752375100342200ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.Bytes; import net.openhft.lang.io.NativeBytes; import org.jetbrains.annotations.NotNull; import org.junit.Test; import sun.nio.ch.DirectBuffer; import java.nio.ByteBuffer; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey * Date: 20/09/13 * Time: 09:28 */ public class ByteMarshallableMarshallerTest { @Test public void testMarshallable() { int capacity = 2 * 1024; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(capacity); long addr = ((DirectBuffer) byteBuffer).address(); NativeBytes nativeBytes = new NativeBytes(addr, addr, addr + capacity); BytesMarshallable bm = new MockBytesMarshallable(12345678); nativeBytes.writeObject(bm); nativeBytes.finish(); nativeBytes.reset(); BytesMarshallable bm2 = nativeBytes.readObject(MockBytesMarshallable.class); assertEquals(bm, bm2); } static class MockBytesMarshallable implements BytesMarshallable { long number; MockBytesMarshallable(long number) { this.number = number; } @Override public void readMarshallable(@NotNull Bytes in) throws IllegalStateException { number = in.readLong(); } @Override public void writeMarshallable(@NotNull Bytes out) { out.writeLong(number); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MockBytesMarshallable that = (MockBytesMarshallable) o; if (number != that.number) return false; return true; } } } ExternalizableMarshallerTest.java000066400000000000000000000045441226752375100337610ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.NativeBytes; import org.junit.Test; import sun.nio.ch.DirectBuffer; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.nio.ByteBuffer; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey * Date: 20/09/13 * Time: 09:28 */ public class ExternalizableMarshallerTest { @Test public void testMarshallable() { int capacity = 2 * 1024; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(capacity); long addr = ((DirectBuffer) byteBuffer).address(); NativeBytes nativeBytes = new NativeBytes(addr, addr, addr + capacity); Externalizable bm = new MockExternalizable(12345678); nativeBytes.writeObject(bm); nativeBytes.finish(); nativeBytes.reset(); Externalizable bm2 = nativeBytes.readObject(MockExternalizable.class); assertEquals(bm, bm2); } static class MockExternalizable implements Externalizable { long number; MockExternalizable(long number) { this.number = number; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeLong(number); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { number = in.readLong(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MockExternalizable that = (MockExternalizable) o; if (number != that.number) return false; return true; } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/RawCopierTest.java000066400000000000000000000051511226752375100307420ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.DirectBytes; import net.openhft.lang.io.DirectStore; import net.openhft.lang.io.NativeBytes; import org.junit.Test; import java.awt.geom.Point2D; import java.util.Map; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey Date: 22/09/13 Time: 17:06 */ public class RawCopierTest { static void printInts(Object o, int len) { for (long i = 0; i < len; i += 4) { System.out.print(NativeBytes.UNSAFE.getInt(o, i) + " "); } System.out.println(); } @Test public void testStartEnd() { RawCopier aRawCopier = RawCopier.copies(A.class); if (aRawCopier.start != 8) assertEquals(12, aRawCopier.start); assertEquals(aRawCopier.start + 3 * 4, aRawCopier.end); RawCopier bRawCopier = RawCopier.copies(B.class); if (aRawCopier.start != 8) assertEquals(16, bRawCopier.start); assertEquals(bRawCopier.start + 4 * 8, bRawCopier.end); } @Test public void testReadWrite() { DirectStore ds = new DirectStore(null, 1024); DirectBytes db = ds.createSlice(); RawCopier aRawCopier = RawCopier.copies(A.class); A a = new A(); a.i = 111; a.j = -222; a.k = 333; a.s = "Hello"; aRawCopier.toBytes(a, db); assertEquals(12, db.position()); assertEquals(111, db.readInt(0)); assertEquals(-222, db.readInt(4)); assertEquals(333, db.readInt(8)); A a2 = new A(); a2.i = 1; a2.j = 2; a2.k = 3; // printInts(a2, 28); db.position(0); aRawCopier.fromBytes(db, a2); // printInts(a2, 28); assertEquals(111, a2.i); assertEquals(-222, a2.j); assertEquals(333, a2.k); assertEquals(null, a2.s); } static class A { int i, j, k; String s; transient Map map; } static class B extends Point2D.Double { double z, w; } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/VanillaBytesMarshallerTest.java000066400000000000000000000041241226752375100334560ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.io.serialization; import net.openhft.lang.io.DirectBytes; import net.openhft.lang.io.DirectStore; import net.openhft.lang.io.NativeBytes; import org.junit.Test; import sun.nio.ch.DirectBuffer; import java.nio.ByteBuffer; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey Date: 20/09/13 Time: 09:28 */ public class VanillaBytesMarshallerTest { @Test public void testObjects() { DirectBytes bytes = new DirectStore(1024).createSlice(); Object[] objects = {1, 1L, 1.0, "Hello"}; for (Object o : objects) { long pos = bytes.position(); bytes.writeObject(o); System.out.printf("%s used %,d bytes%n", o.getClass(), bytes.position() - pos); } bytes.reset(); for (Object o : objects) { Object o2 = bytes.readObject(); assertEquals(o, o2); } } @Test public void testMarshallable() { int capacity = 2 * 1024; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(capacity); long addr = ((DirectBuffer) byteBuffer).address(); NativeBytes nativeBytes = new NativeBytes(addr, addr, addr + capacity); nativeBytes.writeObject(BuySell.BUY); nativeBytes.writeObject(BuySell.SELL); nativeBytes.finish(); nativeBytes.reset(); assertEquals(BuySell.BUY, nativeBytes.readObject()); assertEquals(BuySell.SELL, nativeBytes.readObject()); } enum BuySell { BUY, SELL } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/direct/000077500000000000000000000000001226752375100266145ustar00rootroot00000000000000DirectSerializationFilterTest.java000066400000000000000000000056741226752375100353720ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/directpackage net.openhft.lang.io.serialization.direct; import org.junit.Test; import java.lang.reflect.Field; import java.util.*; import static net.openhft.lang.io.serialization.direct.DirectSerializationFilter.stopAtFirstIneligibleField; import static org.junit.Assert.*; public class DirectSerializationFilterTest { @Test public void instancePrimitivesAreEligible() { List field = fieldsNamed("intField"); assertEquals(field, stopAtFirstIneligibleField(field)); } @Test public void instancePrimitiveArraysAreNotEligible() { List field = fieldsNamed("doubleArray"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void instanceReferencesAreNotEligible() { List field = fieldsNamed("stringList"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void instanceReferenceArraysAreNotEligible() { List field = fieldsNamed("objectArray"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void staticPrimitivesAreNotEligible() { List field = fieldsNamed("staticIntField"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void staticPrimitiveArraysAreNotEligible() { List field = fieldsNamed("staticDoubleArray"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void staticReferencesAreNotEligible() { List field = fieldsNamed("staticStringList"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void staticReferenceArraysAreNotEligible() { List field = fieldsNamed("staticObjectArray"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void transientPrimitivesAreNotEligible() { List field = fieldsNamed("transientShort"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void transientReferencsAreNotEligible() { List field = fieldsNamed("transientObject"); assertTrue(stopAtFirstIneligibleField(field).isEmpty()); } @Test public void includesAllEligibleFields() { List fields = fieldsNamed("intField", "shortField", "longField", "byteField", "stringList"); List expectedfields = fields.subList(0, 4); assertEquals(expectedfields, stopAtFirstIneligibleField(fields)); } private static List fieldsNamed(String... names) { ArrayList fields = new ArrayList(); for (String name : names) { try { fields.add(TestClasses.MixedFields.class.getDeclaredField(name)); } catch (NoSuchFieldException e) { throw new RuntimeException("Exception retrieving " + name, e); } } return fields; } } DirectSerializationMetadataTest.java000066400000000000000000000062111226752375100356510ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/directpackage net.openhft.lang.io.serialization.direct; import org.junit.Test; import static net.openhft.lang.io.AbstractBytes.UNSIGNED_INT_MASK; import static net.openhft.lang.io.NativeBytes.UNSAFE; import static net.openhft.lang.io.serialization.direct.DirectSerializationMetadata.*; import static net.openhft.lang.io.serialization.direct.TestClasses.*; import static org.junit.Assert.assertEquals; public class DirectSerializationMetadataTest { @Test public void primitives1Metadata() { unsafeClassHeaderSize64BitCompressedOops(new Primitives1()); SerializationMetadata serializationMetadata = extractMetadata(Introspect.fields(Primitives1.class)); assertEquals(OBJECT_HEADER_SIZE, serializationMetadata.start); assertEquals(4, serializationMetadata.length); } @Test public void primitives2Metadata() { unsafeClassHeaderSize64BitCompressedOops(new Primitives2()); SerializationMetadata serializationMetadata = extractMetadata(Introspect.fields(Primitives2.class)); assertEquals(OBJECT_HEADER_SIZE, serializationMetadata.start); assertEquals(12, serializationMetadata.length); } @Test public void primitives3Metadata() { unsafeClassHeaderSize64BitCompressedOops(new Primitives3()); SerializationMetadata serializationMetadata = extractMetadata(Introspect.fields(Primitives3.class)); assertEquals(OBJECT_HEADER_SIZE, serializationMetadata.start); assertEquals(12, serializationMetadata.length); } @Test public void primitives4Metadata() { unsafeClassHeaderSize64BitCompressedOops(new Primitives4()); SerializationMetadata serializationMetadata = extractMetadata(Introspect.fields(Primitives4.class)); assertEquals(OBJECT_HEADER_SIZE, serializationMetadata.start); assertEquals(4, serializationMetadata.length); } @Test public void primitives5Metadata() { unsafeClassHeaderSize64BitCompressedOops(new Primitives5()); SerializationMetadata serializationMetadata = extractMetadata(Introspect.fields(Primitives5.class)); assertEquals(OBJECT_HEADER_SIZE, serializationMetadata.start); assertEquals(12, serializationMetadata.length); } @Test public void primitives6Metadata() { unsafeClassHeaderSize64BitCompressedOops(new Primitives6()); SerializationMetadata serializationMetadata = extractMetadata(Introspect.fields(Primitives6.class)); assertEquals(OBJECT_HEADER_SIZE, serializationMetadata.start); assertEquals(28, serializationMetadata.length); } private void unsafeClassHeaderSize64BitCompressedOops(Object instance) { if (System.getProperty("useUnsafeClassHeaders") != null) { long narrowKlassPointer = UNSAFE.getInt(instance, NATIVE_WORD_SIZE) & UNSIGNED_INT_MASK; long wideKlassPointer = narrowKlassPointer << 3; long sizeField = wideKlassPointer + 3 * UNSAFE.addressSize(); System.out.println(String.format("Size of %s is %s", instance.getClass().getName(), UNSAFE.getAddress(sizeField) & UNSIGNED_INT_MASK)); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/direct/IntrospectTest.java000066400000000000000000000017101226752375100324500ustar00rootroot00000000000000package net.openhft.lang.io.serialization.direct; import org.junit.Test; import java.lang.reflect.Field; import java.util.*; import static net.openhft.lang.io.serialization.direct.TestClasses.*; import static org.junit.Assert.assertEquals; public class IntrospectTest { @Test public void returnsFieldsRegardlessOfVisibility() { List fields = asFieldList(InstanceOnlyNoStaticFields.class); assertEquals(3, fields.size()); } @Test public void returnsStaticAsWellAsInstanceFields() { List fields = asFieldList(HasInstanceAndStaticFields.class); assertEquals(6, fields.size()); } @Test public void walksClassHierarchyForAllFields() { List fields = asFieldList(LevelTwoDerivedClass.class); assertEquals(6, fields.size()); } private static List asFieldList(Class clazz) { return new ArrayList(Introspect.fields(clazz)); } } ObjectMarshallerTest.java000066400000000000000000000150201226752375100334570ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/directpackage net.openhft.lang.io.serialization.direct; import net.openhft.lang.io.*; import org.junit.Test; import java.nio.ByteBuffer; import java.util.Collections; import static net.openhft.lang.io.serialization.direct.TestClasses.*; import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; public class ObjectMarshallerTest { @Test public void marshalAndUnmarshalPrimitives1() { Primitives1 p = new Primitives1(); p.a = 55; Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(Primitives1.class); marshaller.write(b, p); p.a = 0; b.reset(); marshaller.read(b, p); assertEquals(55, p.a); b.reset(); Primitives1 newP = new Primitives1(); marshaller.read(b, newP); assertEquals(55, newP.a); } @Test public void marshalAndUnmarshalPrimitives2() { Primitives2 p = new Primitives2(); p.a = 55; p.b = -10; Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(Primitives2.class); marshaller.write(b, p); p.a = 0; p.b = 0; b.reset(); marshaller.read(b, p); assertEquals(55, p.a); assertEquals(-10, p.b); b.reset(); Primitives2 newP = new Primitives2(); marshaller.read(b, newP); assertEquals(55, newP.a); assertEquals(-10, newP.b); } @Test public void marshalAndUnmarshalPrimitives3() { Primitives3 p = new Primitives3(); p.a = 55; p.b = -10; p.c = 92; Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(Primitives3.class); marshaller.write(b, p); p.a = 0; p.b = 0; p.c = 0; b.reset(); marshaller.read(b, p); assertEquals(55, p.a); assertEquals(-10, p.b); assertEquals(92, p.c); b.reset(); Primitives3 newP = new Primitives3(); marshaller.read(b, newP); assertEquals(55, newP.a); assertEquals(-10, newP.b); assertEquals(92, newP.c); } @Test public void marshalAndUnmarshalPrimitives4() { Primitives4 p = new Primitives4(); p.a = true; Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(Primitives4.class); marshaller.write(b, p); p.a = false; b.reset(); marshaller.read(b, p); assertTrue(p.a); b.reset(); Primitives4 newP = new Primitives4(); marshaller.read(b, newP); assertTrue(newP.a); } @Test public void marshalAndUnmarshalPrimitives5() { Primitives5 p = new Primitives5(); p.a = true; p.b = Long.MIN_VALUE; Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(Primitives5.class); marshaller.write(b, p); p.a = false; p.b = 0; b.reset(); marshaller.read(b, p); assertTrue(p.a); assertEquals(Long.MIN_VALUE, p.b); b.reset(); Primitives5 newP = new Primitives5(); marshaller.read(b, newP); assertTrue(newP.a); assertEquals(Long.MIN_VALUE, newP.b); } @Test public void marshalAndUnmarshalPrimitives6() { Primitives6 p = new Primitives6(); p.a = true; p.b = Integer.MAX_VALUE; p.c = Short.MAX_VALUE; p.d = Long.MAX_VALUE; p.e = Double.MAX_VALUE; Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(Primitives6.class); marshaller.write(b, p); p.a = false; p.b = 0; p.c = 0; p.d = 0; p.e = 0; b.reset(); marshaller.read(b, p); assertTrue(p.a); assertEquals(Integer.MAX_VALUE, p.b); assertEquals(Short.MAX_VALUE, p.c); assertEquals(Long.MAX_VALUE, p.d); assertEquals(Double.MAX_VALUE, p.e, 0); b.reset(); Primitives6 newP = new Primitives6(); marshaller.read(b, newP); assertTrue(newP.a); assertEquals(Integer.MAX_VALUE, p.b); assertEquals(Short.MAX_VALUE, p.c); assertEquals(Long.MAX_VALUE, p.d); assertEquals(Double.MAX_VALUE, p.e, 0); } @Test public void marshalAndUnmarshalMixedClass() { MixedFields m = new MixedFields(); m.intField = Integer.MIN_VALUE + 1; m.byteField = Byte.MAX_VALUE - 1; m.shortField = Short.MIN_VALUE + 1; m.longField = Long.MAX_VALUE - 1; m.doubleArray = new double[]{-50.0, 50.0}; m.stringList = Collections.singletonList("Foo"); m.objectArray = new Object[]{new Primitives1()}; m.transientShort = 12; m.transientObject = new Primitives2(); Bytes b = createByteStore(); ObjectMarshaller marshaller = ObjectMarshallers.forClass(MixedFields.class); marshaller.write(b, m); m.intField = 0; m.byteField = 0; m.shortField = 0; m.longField = 0; m.doubleArray = null; m.stringList = null; m.objectArray = null; m.transientShort = 0; m.transientObject = null; b.reset(); marshaller.read(b, m); assertEquals(Integer.MIN_VALUE + 1, m.intField); assertEquals(0, m.byteField); // because of jvm field rearrangement the two shorts are packed into 4 bytes and this eligible field is skipped assertEquals(Short.MIN_VALUE + 1, m.shortField); assertEquals(Long.MAX_VALUE - 1, m.longField); assertNull(m.doubleArray); assertNull(m.stringList); assertNull(m.objectArray); assertNull(m.transientObject); assertEquals(0, m.transientShort); b.reset(); MixedFields newM = new MixedFields(); marshaller.read(b, newM); assertEquals(Integer.MIN_VALUE + 1, newM.intField); assertEquals(0, newM.byteField); assertEquals(Short.MIN_VALUE + 1, newM.shortField); assertEquals(Long.MAX_VALUE - 1, newM.longField); assertNull(newM.doubleArray); assertNull(newM.stringList); assertNull(newM.objectArray); assertNull(newM.transientObject); assertEquals(0, newM.transientShort); } private ByteBufferBytes createByteStore() { return new ByteBufferBytes(ByteBuffer.allocate(64)); } }Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/io/serialization/direct/TestClasses.java000066400000000000000000000043101226752375100317120ustar00rootroot00000000000000package net.openhft.lang.io.serialization.direct; import java.util.*; class TestClasses { public static class InstanceOnlyNoStaticFields { public int intField; protected String stringField; private Object objectField; } public static class HasInstanceAndStaticFields { public static int staticIntField; protected static String staticStringField; private static Object staticObjectField; public int intField; protected String stringField; private Object objectField; } public static class BaseClass { private static double staticBaseDoubleField; protected List baseListField; } public static class LevelOneDerivedClass extends BaseClass { protected static Object staticLevelOneObjectField; public long levelOneLongField; } public static class LevelTwoDerivedClass extends LevelOneDerivedClass { public static String staticLevelTwoStringField; final int levelTwoDerivedIntField = 0; } public static class MixedFields { public static int staticIntField ; public static double[] staticDoubleArray; public static List staticStringList = Collections.singletonList("S1"); public static Object[] staticObjectArray = {new Object()}; public int intField; public byte byteField; public short shortField; public long longField; public double[] doubleArray; public List stringList; public Object[] objectArray; transient short transientShort; public transient Object transientObject; } public static class Primitives1 { public int a; } public static class Primitives2 { public int a, b; } public static class Primitives3 { public int a, b; public short c; } public static class Primitives4 { public boolean a; } public static class Primitives5 { public boolean a; public long b; } public static class Primitives6 { public boolean a; public int b; public short c; public long d; public double e; } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/000077500000000000000000000000001226752375100231565ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/DataValueGeneratorTest.java000066400000000000000000000141721226752375100304030ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.compiler.CachedCompiler; import net.openhft.lang.io.ByteBufferBytes; import net.openhft.lang.io.Bytes; import org.junit.Test; import java.nio.ByteBuffer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * User: peter.lawrey Date: 06/10/13 Time: 20:13 */ public class DataValueGeneratorTest { @Test public void testGenerateJavaCode() throws Exception { DataValueGenerator dvg = new DataValueGenerator(); // dvg.setDumpCode(true); JavaBeanInterface jbi = dvg.heapInstance(JavaBeanInterface.class); jbi.setByte((byte) 1); jbi.setChar('2'); jbi.setShort((short) 3); jbi.setInt(4); jbi.setFloat(5); jbi.setLong(6); jbi.setDouble(7); jbi.setFlag(true); assertEquals(1, jbi.getByte()); assertEquals('2', jbi.getChar()); assertEquals(3, jbi.getShort()); assertEquals(4, jbi.getInt()); assertEquals(5.0, jbi.getFloat(), 0); assertEquals(6, jbi.getLong()); assertEquals(7.0, jbi.getDouble(), 0.0); assertTrue(jbi.getFlag()); } @Test public void testGenerateJavaCode2() throws Exception { DataValueGenerator dvg = new DataValueGenerator(); MinimalInterface mi = dvg.heapInstance(MinimalInterface.class); mi.byte$((byte) 1); mi.char$('2'); mi.short$((short) 3); mi.int$(4); mi.float$(5); mi.long$(6); mi.double$(7); mi.flag(true); assertEquals(1, mi.byte$()); assertEquals('2', mi.char$()); assertEquals(3, mi.short$()); assertEquals(4, mi.int$()); assertEquals(5.0, mi.float$(), 0); assertEquals(6, mi.long$()); assertEquals(7.0, mi.double$(), 0.0); assertTrue(mi.flag()); ByteBufferBytes bbb = new ByteBufferBytes(ByteBuffer.allocate(64)); mi.writeMarshallable(bbb); System.out.println("size: " + bbb.position()); MinimalInterface mi2 = dvg.heapInstance(MinimalInterface.class); bbb.position(0); mi2.readMarshallable(bbb); assertEquals(1, mi2.byte$()); assertEquals('2', mi2.char$()); assertEquals(3, mi2.short$()); assertEquals(4, mi2.int$()); assertEquals(5.0, mi2.float$(), 0); assertEquals(6, mi2.long$()); assertEquals(7.0, mi2.double$(), 0.0); assertTrue(mi2.flag()); } @Test public void testGenerateNative() throws Exception { String actual = new DataValueGenerator().generateNativeObject(JavaBeanInterface.class); // System.out.println(actual); CachedCompiler cc = new CachedCompiler(null, null); Class aClass = cc.loadFromJava(JavaBeanInterface.class.getName() + "£native", actual); JavaBeanInterface jbi = (JavaBeanInterface) aClass.asSubclass(JavaBeanInterface.class).newInstance(); Bytes bytes = new ByteBufferBytes(ByteBuffer.allocate(64)); ((Byteable) jbi).bytes(bytes); jbi.setByte((byte) 1); jbi.setChar('2'); jbi.setShort((short) 3); jbi.setInt(4); jbi.setFloat(5); jbi.setLong(6); jbi.setDouble(7); jbi.setFlag(true); assertEquals("", jbi.getString()); jbi.setString("G'day"); assertEquals(1, jbi.getByte()); assertEquals('2', jbi.getChar()); assertEquals(3, jbi.getShort()); assertEquals(4, jbi.getInt()); assertEquals(5.0, jbi.getFloat(), 0); assertEquals(6, jbi.getLong()); assertEquals(7.0, jbi.getDouble(), 0.0); assertTrue(jbi.getFlag()); assertEquals("G'day", jbi.getString()); assertEquals(42, ((Byteable) jbi).maxSize()); } @Test public void testStringFields() { DataValueGenerator dvg = new DataValueGenerator(); StringInterface si = dvg.heapInstance(StringInterface.class); si.setString("Hello world"); assertEquals("Hello world", si.getString()); StringInterface si2 = dvg.nativeInstance(StringInterface.class); Bytes bytes = new ByteBufferBytes(ByteBuffer.allocate(192)); ((Byteable) si2).bytes(bytes); si2.setString("Hello world £€"); si2.setText("Hello world £€"); assertEquals("Hello world £€", si2.getString()); assertEquals("Hello world £€", si2.getText()); } @Test public void testNested() { DataValueGenerator dvg = new DataValueGenerator(); // dvg.setDumpCode(true); NestedB nestedB1 = dvg.heapInstance(NestedB.class); nestedB1.ask(100); nestedB1.bid(100); NestedB nestedB2 = dvg.heapInstance(NestedB.class); nestedB2.ask(91); nestedB2.bid(92); // dvg.setDumpCode(true); NestedA nestedA = dvg.nativeInstance(NestedA.class); Bytes bytes = new ByteBufferBytes(ByteBuffer.allocate(192)); ((Byteable) nestedA).bytes(bytes); nestedA.key("key"); nestedA.one(nestedB1); nestedA.two(nestedB2); assertEquals("key", nestedA.key()); assertEquals(nestedB1.ask(), nestedA.one().ask(), 0.0); assertEquals(nestedB1.bid(), nestedA.one().bid(), 0.0); assertEquals(nestedB2.ask(), nestedA.two().ask(), 0.0); assertEquals(nestedB2.bid(), nestedA.two().bid(), 0.0); assertEquals(nestedB1, nestedA.one()); assertEquals(nestedB2, nestedA.two()); assertEquals(nestedB1.hashCode(), nestedA.one().hashCode()); assertEquals(nestedB2.hashCode(), nestedA.two().hashCode()); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/DataValueModelTest.java000066400000000000000000000142121226752375100275100ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey Date: 06/10/13 Time: 18:12 */ public class DataValueModelTest { @Test public void testAcquire() { DataValueModel midvm = DataValueModels.acquireModel(MinimalInterface.class); assertEquals("{byte$=FieldModel{name='byte$', getter=public abstract byte net.openhft.lang.model.MinimalInterface.byte$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.byte$(byte)}\n" + " char$=FieldModel{name='char$', getter=public abstract char net.openhft.lang.model.MinimalInterface.char$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.char$(char)}\n" + " double$=FieldModel{name='double$', getter=public abstract double net.openhft.lang.model.MinimalInterface.double$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.double$(double)}\n" + " flag=FieldModel{name='flag', getter=public abstract boolean net.openhft.lang.model.MinimalInterface.flag(), setter=public abstract void net.openhft.lang.model.MinimalInterface.flag(boolean)}\n" + " float$=FieldModel{name='float$', getter=public abstract float net.openhft.lang.model.MinimalInterface.float$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.float$(float)}\n" + " int$=FieldModel{name='int$', getter=public abstract int net.openhft.lang.model.MinimalInterface.int$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.int$(int)}\n" + " long$=FieldModel{name='long$', getter=public abstract long net.openhft.lang.model.MinimalInterface.long$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.long$(long)}\n" + " short$=FieldModel{name='short$', getter=public abstract short net.openhft.lang.model.MinimalInterface.short$(), setter=public abstract void net.openhft.lang.model.MinimalInterface.short$(short)}}" , midvm.fieldMap().toString().replaceAll("},", "}\n")); DataValueModel jbdvm = DataValueModels.acquireModel(JavaBeanInterface.class); assertEquals("{byte=FieldModel{name='byte', getter=public abstract byte net.openhft.lang.model.JavaBeanInterface.getByte(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setByte(byte)}\n" + " char=FieldModel{name='char', getter=public abstract char net.openhft.lang.model.JavaBeanInterface.getChar(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setChar(char)}\n" + " double=FieldModel{name='double', getter=public abstract double net.openhft.lang.model.JavaBeanInterface.getDouble(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setDouble(double)}\n" + " flag=FieldModel{name='flag', getter=public abstract boolean net.openhft.lang.model.JavaBeanInterface.getFlag(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setFlag(boolean)}\n" + " float=FieldModel{name='float', getter=public abstract float net.openhft.lang.model.JavaBeanInterface.getFloat(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setFloat(float)}\n" + " int=FieldModel{name='int', getter=public abstract int net.openhft.lang.model.JavaBeanInterface.getInt(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setInt(int)}\n" + " long=FieldModel{name='long', getter=public abstract long net.openhft.lang.model.JavaBeanInterface.getLong(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setLong(long)}\n" + " record=FieldModel{name='record', getter=public abstract int net.openhft.lang.model.JavaBeanInterface.getRecord(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setRecord(int)}\n" + " short=FieldModel{name='short', getter=public abstract short net.openhft.lang.model.JavaBeanInterface.getShort(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setShort(short)}\n" + " string=FieldModel{name='string', getter=public abstract java.lang.String net.openhft.lang.model.JavaBeanInterface.getString(), setter=public abstract void net.openhft.lang.model.JavaBeanInterface.setString(java.lang.String), size= @net.openhft.lang.model.constraints.MaxSize(value=8)}}" , jbdvm.fieldMap().toString().replaceAll("},", "}\n")); DataValueModel nais = DataValueModels.acquireModel(NestedArrayInterface.class); assertEquals("{int=FieldModel{name='int', getter=public abstract int net.openhft.lang.model.NestedArrayInterface.getInt(int), setter=public abstract void net.openhft.lang.model.NestedArrayInterface.setInt(int,int), indexSize= @net.openhft.lang.model.constraints.MaxSize(value=16)}\n" + " jBI=FieldModel{name='jBI', getter=public abstract net.openhft.lang.model.JavaBeanInterface net.openhft.lang.model.NestedArrayInterface.getJBI(int), setter=public abstract void net.openhft.lang.model.NestedArrayInterface.setJBI(int,net.openhft.lang.model.JavaBeanInterface), indexSize= @net.openhft.lang.model.constraints.MaxSize(value=32)}\n" + " text=FieldModel{name='text', getter=public abstract java.lang.String net.openhft.lang.model.NestedArrayInterface.getText(), setter=public abstract void net.openhft.lang.model.NestedArrayInterface.setText(java.lang.String)}}" , nais.fieldMap().toString().replaceAll("},", "}\n")); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/JavaBeanInterface.java000066400000000000000000000025661226752375100273220ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.model.constraints.MaxSize; /** * User: peter.lawrey * Date: 06/10/13 * Time: 16:59 */ public interface JavaBeanInterface { int getRecord(); void setRecord(int record); void busyLockRecord() throws InterruptedException; void unlockRecord(); void setFlag(boolean flag); boolean getFlag(); void setByte(byte b); byte getByte(); void setShort(short s); short getShort(); void setChar(char ch); char getChar(); void setInt(int i); int getInt(); void setFloat(float f); float getFloat(); void setLong(long l); long getLong(); void setDouble(double d); double getDouble(); void setString(@MaxSize(8) String s); String getString(); } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/MinimalInterface.java000066400000000000000000000023171226752375100272330ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.io.serialization.BytesMarshallable; /** * User: peter.lawrey * Date: 06/10/13 * Time: 16:59 */ public interface MinimalInterface extends BytesMarshallable, Copyable, Byteable { void flag(boolean flag); boolean flag(); void byte$(byte b); byte byte$(); void short$(short s); short short$(); void char$(char ch); char char$(); void int$(int i); int int$(); void float$(float f); float float$(); void long$(long l); long long$(); void double$(double d); double double$(); } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/NestedA.java000066400000000000000000000016411226752375100253460ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.model.constraints.MaxSize; /** * User: peter.lawrey * Date: 08/10/13 * Time: 10:11 */ public interface NestedA { void key(@MaxSize String key); String key(); void one(NestedB one); NestedB one(); void two(NestedB one); NestedB two(); } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/NestedArrayInterface.java000066400000000000000000000017221226752375100300650ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.model.constraints.MaxSize; /** */ public interface NestedArrayInterface { String getText(); void setText(String text); int getInt(int index); void setInt(@MaxSize(16) int index, int value); JavaBeanInterface getJBI(@MaxSize(32) int index); void setJBI(int index, JavaBeanInterface jbi); } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/NestedB.java000066400000000000000000000015641226752375100253530ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.model.constraints.Digits; /** * User: peter.lawrey * Date: 08/10/13 * Time: 10:24 */ public interface NestedB { void bid(@Digits double bid); double bid(); void ask(@Digits double ask); double ask(); } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/model/StringInterface.java000066400000000000000000000016231226752375100271120ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.model; import net.openhft.lang.model.constraints.MaxSize; /** * User: peter.lawrey * Date: 08/10/13 * Time: 09:09 */ public interface StringInterface { void setString(@MaxSize(64) String s); String getString(); void setText(@MaxSize String s); String getText(); } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/testing/000077500000000000000000000000001226752375100235335ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/testing/RunningMinimumTest.java000066400000000000000000000032001226752375100302050ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.testing; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * User: peter.lawrey * Date: 05/08/13 * Time: 19:14 */ public class RunningMinimumTest { @Test public void testSample() throws Exception { for (int k = 0; k < 1000; k++) { for (long delta : new long[]{0, Integer.MIN_VALUE, Integer.MAX_VALUE}) { RunningMinimum rm = new RunningMinimum(50 * 1000); int j; for (j = 0; j < 50 * 1000000; j += 1000000) { long startTime = System.nanoTime() + j; long endTime = System.nanoTime() + j + delta + (long) (Math.pow(10 * 1000, Math.random()) * 1000); rm.sample(startTime, endTime); } assertEquals("delta=" + delta, delta, rm.minimum(), 40 * 1000); } } } @Test public void testVanillaDiff() { VanillaDifferencer vd = new VanillaDifferencer(); assertEquals(100, vd.sample(123400, 123500)); } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/values/000077500000000000000000000000001226752375100233555ustar00rootroot00000000000000Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/values/CheckValuesBuildTest.java000066400000000000000000000031571226752375100302430ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; import net.openhft.lang.model.DataValueGenerator; import org.junit.Test; /** * User: peter.lawrey * Date: 10/10/13 * Time: 11:38 */ public class CheckValuesBuildTest { @Test public void testValuesCompile() throws ClassNotFoundException { DataValueGenerator dvg = new DataValueGenerator(); for (Class clazz : new Class[]{ IntValue.class, ByteValue.class, CharValue.class, ShortValue.class, Int24Value.class, FloatValue.class, DoubleValue.class, LongValue.class, StringValue.class, BooleanValue.class, UnsignedByteValue.class, UnsignedIntValue.class, UnsignedShortValue.class, NestAll.class }) { System.out.println(dvg.acquireHeapClass(clazz).getName() + " " + dvg.acquireNativeClass(clazz).getName()); } } } Java-Lang-6.1.4/lang/src/test/java/net/openhft/lang/values/NestAll.java000066400000000000000000000021511226752375100255610ustar00rootroot00000000000000/* * Copyright 2013 Peter Lawrey * * 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 net.openhft.lang.values; /** * User: peter.lawrey * Date: 11/10/13 * Time: 08:59 */ public interface NestAll { BooleanValue getBoolean(); ByteValue getByte(); CharValue getChar(); DoubleValue getDouble(); FloatValue getFloat(); Int24Value getInt24(); Int48Value getInt48(); IntValue getInt(); LongValue getLong(); ShortValue getShort(); StringValue getString(); UnsignedByteValue getUB(); UnsignedIntValue getUI(); UnsignedShortValue getUS(); } Java-Lang-6.1.4/pom.xml000066400000000000000000000024261226752375100146150ustar00rootroot00000000000000 4.0.0 net.openhft Java-Lang 6.1.3 pom Java Lang Parent High Performance Java Lang library lang lang-osgi lang-integration