├── .gitignore
├── LICENSE
├── README.md
├── measures
├── jmh-results
│ ├── city11hash.txt
│ ├── murmur3Hash.txt
│ └── vanillaHash.txt
├── pom.xml
└── src
│ └── main
│ └── java
│ └── net
│ └── openhft
│ └── chronicle
│ └── algorithms
│ └── measures
│ ├── AddressWrapper.java
│ ├── AddressWrappers.java
│ ├── AvalancheScore.java
│ ├── CheckMain.java
│ ├── MainBytes.java
│ ├── MaskHashScore.java
│ └── OrtogonalBitsScore.java
├── pom.xml
└── src
├── main
└── java
│ └── net
│ └── openhft
│ └── chronicle
│ └── algo
│ ├── MemoryUnit.java
│ ├── bitset
│ ├── BitSet.java
│ ├── BitSetAlgorithm.java
│ ├── BitSetFrame.java
│ ├── ConcurrentFlatBitSetFrame.java
│ ├── FlatBitSetAlgorithm.java
│ ├── ReusableBitSet.java
│ └── SingleThreadedFlatBitSetFrame.java
│ ├── bytes
│ ├── Access.java
│ ├── AccessCommon.java
│ ├── Accessor.java
│ ├── ArrayAccessors.java
│ ├── ByteBufferAccess.java
│ ├── ByteBufferAccessor.java
│ ├── BytesAccesses.java
│ ├── BytesAccessors.java
│ ├── CharSequenceAccess.java
│ ├── CharSequenceAccessor.java
│ ├── HotSpotStringAccessor.java
│ ├── NativeAccess.java
│ ├── RandomDataInputAccess.java
│ ├── RandomDataOutputAccess.java
│ ├── ReadAccess.java
│ ├── WriteAccess.java
│ └── ZeroAccess.java
│ ├── hashing
│ ├── CityHash_1_1.java
│ ├── LongHashFunction.java
│ ├── MurmurHash_3.java
│ ├── Primitives.java
│ └── XxHash_r39.java
│ ├── internal
│ └── package-info.java
│ └── locks
│ ├── AbstractReadWriteLockState.java
│ ├── AbstractReadWriteLockingStrategy.java
│ ├── AcquisitionStrategies.java
│ ├── AcquisitionStrategy.java
│ ├── LockState.java
│ ├── LockingStrategy.java
│ ├── ReadWriteLockState.java
│ ├── ReadWriteLockingStrategy.java
│ ├── ReadWriteUpdateLockState.java
│ ├── ReadWriteUpdateLockingStrategy.java
│ ├── ReadWriteUpdateWithWaitsLockState.java
│ ├── ReadWriteUpdateWithWaitsLockingStrategy.java
│ ├── ReadWriteWithWaitsLockState.java
│ ├── ReadWriteWithWaitsLockingStrategy.java
│ ├── TryAcquireOperation.java
│ ├── TryAcquireOperations.java
│ ├── VanillaReadWriteUpdateWithWaitsLockingStrategy.java
│ └── VanillaReadWriteWithWaitsLockingStrategy.java
└── test
├── java
└── net
│ └── openhft
│ └── chronicle
│ ├── algo
│ ├── bitset
│ │ └── DirectBitSetTest.java
│ ├── hashing
│ │ ├── City64MoreTest.java
│ │ ├── City64_1_1_Test.java
│ │ ├── HashSearcherMain.java
│ │ ├── HashTest.java
│ │ ├── HashTesterMain.java
│ │ ├── HashTesterRunner.java
│ │ ├── LongHashFunctionTest.java
│ │ ├── MurmurHash3MoreTest.java
│ │ ├── MurmurHash3Test.java
│ │ ├── RandomOptimiser.java
│ │ └── XxHash_r39_Test.java
│ └── locks
│ │ └── LockingStrategyTest.java
│ └── map
│ └── locks
│ └── ChronicleStampedLockTest.java
└── resources
└── ftse350.csv
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Package Files #
4 | *.jar
5 | *.war
6 | *.ear
7 |
8 | # IntelliJ
9 | *.iml
10 | *.ipr
11 | *.iws
12 | .idea
13 | compat_reports
14 |
15 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
16 | hs_err_pid*
17 |
18 | # Eclipse
19 | .classpath
20 | .project
21 | .settings/
22 |
23 | # maven
24 | target
25 |
26 | # tests
27 | *.bin
28 | *.deleteme
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | == Copyright 2016 higherfrequencytrading.com
2 |
3 | Licensed under the *Apache License, Version 2.0* (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Chronicle-Algorithms
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Zero allocation, efficient algorithms for
11 | - hashing
12 | - bit set operations
13 | - access the raw bytes of an data type
14 | - off heap locking
15 |
--------------------------------------------------------------------------------
/measures/pom.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 | 4.0.0
20 |
21 | net.openhft
22 | chronicle-algorithms-benchmarks
23 | 1.0-SNAPSHOT
24 | OpenHFT/Chronicle-Algorithms/Measures
25 | Chronicle-Algorithms-Measures
26 |
27 |
28 | UTF-8
29 |
30 |
31 |
32 |
33 |
34 |
35 | net.openhft
36 | third-party-bom
37 | 3.27ea0
38 | pom
39 | import
40 |
41 |
42 |
43 | net.openhft
44 | chronicle-bom
45 | 2.27ea-SNAPSHOT
46 | pom
47 | import
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | net.openhft
57 | chronicle-algorithms
58 |
59 |
60 | net.openhft
61 | chronicle-bytes
62 |
63 |
64 | org.slf4j
65 | slf4j-simple
66 |
67 |
68 |
69 | org.openjdk.jmh
70 | jmh-core
71 |
72 |
73 | org.openjdk.jmh
74 | jmh-generator-annprocess
75 | 1.10.4
76 | provided
77 |
78 |
79 |
80 |
81 |
82 |
83 | org.apache.maven.plugins
84 | maven-shade-plugin
85 | 2.2
86 |
87 |
88 | package
89 |
90 | shade
91 |
92 |
93 | ${project.name}.jar
94 |
95 |
97 | net.openhft.chronicle.algorithms.measures.MainBytes
98 |
99 |
100 |
101 |
102 |
106 | *:*
107 |
108 | META-INF/*.SF
109 | META-INF/*.DSA
110 | META-INF/*.RSA
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | org.apache.maven.plugins
124 | maven-install-plugin
125 | 3.0.0-M1
126 |
127 |
128 | maven-jar-plugin
129 | 2.6
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | /**
20 | * Created by peter on 21/08/15.
21 | */
22 | public interface AddressWrapper {
23 | void setAddress(long address, long length);
24 |
25 | long hash();
26 | }
27 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrappers.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | import net.openhft.chronicle.algo.bytes.NativeAccess;
20 | import net.openhft.chronicle.algo.hashing.LongHashFunction;
21 | import net.openhft.chronicle.bytes.Bytes;
22 | import net.openhft.chronicle.bytes.BytesStore;
23 | import net.openhft.chronicle.bytes.PointerBytesStore;
24 | import net.openhft.chronicle.bytes.algo.OptimisedBytesStoreHash;
25 |
26 | import java.security.SecureRandom;
27 | import java.util.Random;
28 |
29 | /**
30 | * Created by peter on 21/08/15.
31 | */
32 | public enum AddressWrappers implements AddressWrapper {
33 | RANDOM {
34 | Random rand = new Random();
35 |
36 | @Override
37 | public void setAddress(long address, long length) {
38 | }
39 | @Override
40 | public long hash() {
41 | return rand.nextLong();
42 | }
43 | },
44 | SECURE_RANDOM {
45 | SecureRandom rand = new SecureRandom();
46 |
47 | @Override
48 | public void setAddress(long address, long length) {
49 | }
50 | @Override
51 | public long hash() {
52 | return rand.nextLong();
53 | }
54 | },
55 |
56 | VANILLA {
57 | int length;
58 | Bytes bytes;
59 |
60 | @Override
61 | public void setAddress(long address, long length) {
62 | this.length = (int) length;
63 | PointerBytesStore pbs = BytesStore.nativePointer();
64 | pbs.set(address, length);
65 | bytes = pbs.bytesForRead().unchecked(true);
66 | }
67 | @Override
68 | public long hash() {
69 | return OptimisedBytesStoreHash.applyAsLong32bytesMultiple(bytes, length);
70 | }
71 | },
72 | CITY_1_1 {
73 | long address,length;
74 |
75 | @Override
76 | public void setAddress(long address, long length) {
77 | this.address = address;
78 | this.length = length;
79 | }
80 | @Override
81 | public long hash() {
82 | return LongHashFunction.city_1_1().hash((Object) null, NativeAccess.instance(), address, length);
83 | }
84 | },
85 | MURMUR_3 {
86 | long address,length;
87 |
88 | @Override
89 | public void setAddress(long address, long length) {
90 | this.address = address;
91 | this.length = length;
92 | }
93 | @Override
94 | public long hash() {
95 | return LongHashFunction.murmur_3().hash((Object) null, NativeAccess.instance(), address, length);
96 | }
97 | },
98 | STRING32 {
99 | Bytes bytes;
100 |
101 | @Override
102 | public void setAddress(long address, long length) {
103 | PointerBytesStore pbs = BytesStore.nativePointer();
104 | pbs.set(address, length);
105 | bytes = pbs.bytesForRead().unchecked(true);
106 | }
107 | @Override
108 | public long hash() {
109 | int hc = 0;
110 | for (int i = 0; i < bytes.length(); i++)
111 | hc = hc * 31 + bytes.charAt(i);
112 |
113 | return hash(hc);
114 | }
115 | // from the hash() function in HashMap
116 | int hash(int h) {
117 | // This function ensures that hashCodes that differ only by
118 | // constant multiples at each bit position have a bounded
119 | // number of collisions (approximately 8 at default load factor).
120 | h ^= (h >>> 20) ^ (h >>> 12);
121 | return h ^ (h >>> 7) ^ (h >>> 4);
122 | }
123 | },
124 | STRING64 {
125 | Bytes bytes;
126 |
127 | @Override
128 | public void setAddress(long address, long length) {
129 | PointerBytesStore pbs = BytesStore.nativePointer();
130 | pbs.set(address, length);
131 | bytes = pbs.bytesForRead().unchecked(true);
132 | }
133 | @Override
134 | public long hash() {
135 | long hc = 0;
136 | for (int i = 0; i < bytes.length(); i++)
137 | hc = hc * 31 + bytes.charAt(i);
138 | return hash(hc);
139 | }
140 | // based on the hash() function in HashMap
141 | long hash(long h) {
142 | h ^= (h >>> 41) ^ (h >>> 23);
143 | return h ^ (h >>> 14) ^ (h >>> 7);
144 | }
145 | },
146 | STRING32_WITHOUT_AGITATE {
147 | Bytes bytes;
148 |
149 | @Override
150 | public void setAddress(long address, long length) {
151 | PointerBytesStore pbs = BytesStore.nativePointer();
152 | pbs.set(address, length);
153 | bytes = pbs.bytesForRead().unchecked(true);
154 | }
155 | @Override
156 | public long hash() {
157 | int hc = 0;
158 | for (int i = 0; i < bytes.length(); i++)
159 | hc = hc * 31 + bytes.charAt(i);
160 |
161 | return hc;
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AvalancheScore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | import net.openhft.chronicle.bytes.NativeBytes;
20 |
21 | import java.security.SecureRandom;
22 | import java.util.Arrays;
23 |
24 | /**
25 | * Created by peter on 22/08/15.
26 | */
27 | public class AvalancheScore {
28 | /**
29 | * Based on the SMHasher Avalanche test
30 | *
31 | * search for biases bits.
32 | * when flipping a single bit of the input, the output should have a 49% - 51% chance of flipping. Some randomness is expected.
33 | *
34 | * @return the worst flip bias.
35 | */
36 | public static double score(AddressWrapper wrapper) {
37 | int runs = 1000;
38 | int bits = 8192;
39 | Double[] scores = new Double[runs];
40 | for (int t = 0; t < runs; t++) {
41 | int[] bitFlipCount = new int[64];
42 | long[] hashs = new long[bits];
43 | byte[] init = new byte[hashs.length / 8];
44 | NativeBytes b = NativeBytes.nativeBytes(init.length);
45 | SecureRandom rand = new SecureRandom();
46 | rand.nextBytes(init);
47 | // low bit count test
48 | if (t % 2 == 0) {
49 | byte[] init2 = new byte[hashs.length / 8];
50 | rand.nextBytes(init2);
51 | for (int i = 0; i < init.length; i++)
52 | init[i] &= init2[i];
53 | }
54 | wrapper.setAddress(b.address(0), b.realCapacity());
55 |
56 | b.clear();
57 | b.write(init);
58 | for (int i = 0; i < hashs.length; i++) {
59 | int index = i >> 6 << 3;
60 | long prev = b.readLong(index);
61 | b.writeLong(index, prev ^ (1L << i));
62 | b.readLimit(hashs.length / 8);
63 | hashs[i] = wrapper.hash();
64 | b.writeLong(index, prev);
65 | }
66 | for (int i = 0; i < hashs.length - 1; i++) {
67 | long diff = hashs[i + 1] ^ hashs[i];
68 | for (int k = 0; k < 64; k++) {
69 | bitFlipCount[k] += (int) ((diff >>> k) & 1);
70 | }
71 | }
72 | long tests = bits - 1;
73 | double sum = 0;
74 | for (int i = 0; i < bitFlipCount.length; i++) {
75 | int count = bitFlipCount[i];
76 | double bitScore = 10000L * count / tests / 100.0;
77 | double err = Math.abs(bitScore - 50);
78 | sum += err;
79 | }
80 | scores[t] = sum / bitFlipCount.length;
81 | }
82 | Arrays.sort(scores);
83 |
84 | double score = scores[runs * 99 / 100];
85 | System.out.printf("Avalanche: The 99%%tile of the drift from 50%% was %.2f%%%n", score);
86 | return score;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/CheckMain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | /**
20 | * Created by peter on 21/08/15.
21 | */
22 | /*
23 | VANILLA
24 | Orthogonal bits: 99%tile score: 6066
25 | Speed: The 99%tile for latency was 0.223 us
26 | Avalanche: The 99%tile of the drift from 50% was 0.55%
27 | Mask of Hash: 99%tile collisions: 1815
28 |
29 | CITY_1_1
30 | Orthogonal bits: 99%tile score: 7395
31 | Speed: The 99%tile for latency was 0.267 us
32 | Avalanche: The 99%tile of the drift from 50% was 0.55%
33 | Mask of Hash: 99%tile collisions: 1817
34 |
35 | MURMUR_3
36 | Orthogonal bits: 99%tile score: 7524
37 | Speed: The 99%tile for latency was 0.378 us
38 | Avalanche: The 99%tile of the drift from 50% was 0.54%
39 | Mask of Hash: 99%tile collisions: 1815
40 |
41 | STRING32
42 | Orthogonal bits: 99%tile score: 295906433
43 | Speed: The 99%tile for latency was 1.580 us
44 | Avalanche: The 99%tile of the drift from 50% was 1.02%
45 | Mask of Hash: 99%tile collisions: 1814
46 |
47 | STRING64
48 | Orthogonal bits: 99%tile score: 1939167
49 | Speed: The 99%tile for latency was 1.520 us
50 | Avalanche: The 99%tile of the drift from 50% was 0.61%
51 | Mask of Hash: 99%tile collisions: 1816
52 | */
53 | public class CheckMain {
54 | public static void main(String[] args) {
55 | for (AddressWrappers aw : AddressWrappers.values()) {
56 | System.out.println(aw);
57 | OrtogonalBitsScore.score(aw);
58 | AvalancheScore.score(aw);
59 | MaskHashScore.score(aw);
60 | System.out.println();
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MainBytes.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | import net.openhft.affinity.Affinity;
20 | import net.openhft.chronicle.algo.hashing.LongHashFunction;
21 | import net.openhft.chronicle.bytes.Bytes;
22 | import net.openhft.chronicle.bytes.algo.OptimisedBytesStoreHash;
23 | import net.openhft.chronicle.core.Jvm;
24 | import org.openjdk.jmh.annotations.*;
25 | import org.openjdk.jmh.runner.Runner;
26 | import org.openjdk.jmh.runner.RunnerException;
27 | import org.openjdk.jmh.runner.options.Options;
28 | import org.openjdk.jmh.runner.options.OptionsBuilder;
29 | import org.openjdk.jmh.runner.options.TimeValue;
30 |
31 | import java.lang.reflect.InvocationTargetException;
32 | import java.lang.reflect.Method;
33 | import java.util.concurrent.TimeUnit;
34 |
35 | @State(Scope.Thread)
36 | public class MainBytes {
37 | static final LongHashFunction city_1_1 = LongHashFunction.city_1_1();
38 | static final LongHashFunction murmur_3 = LongHashFunction.murmur_3();
39 | static final LongHashFunction xx_r39 = LongHashFunction.xx_r39();
40 | Bytes bytes;
41 | long num = 0;
42 | @Param({"16", "64", "256"})
43 | int size;
44 |
45 | public static void main(String... args)
46 | throws RunnerException, InvocationTargetException, IllegalAccessException {
47 | Affinity.setAffinity(2);
48 | if (Jvm.isDebug()) {
49 | MainBytes main = new MainBytes();
50 | main.size = 16;
51 | main.fillBytes();
52 | for (Method m : MainBytes.class.getMethods()) {
53 | if (m.getAnnotation(Benchmark.class) != null) {
54 | m.invoke(main);
55 | }
56 | }
57 | } else {
58 | int time = Jvm.getBoolean("longTest") ? 30 : 2;
59 | System.out.println("measurementTime: " + time + " secs");
60 | Options opt = new OptionsBuilder()
61 | .include(MainBytes.class.getSimpleName())
62 | .mode(Mode.SampleTime)
63 | .measurementTime(TimeValue.seconds(time))
64 | .timeUnit(TimeUnit.NANOSECONDS)
65 | .forks(1)
66 | .build();
67 |
68 | new Runner(opt).run();
69 | }
70 | }
71 | @Setup(Level.Trial)
72 | public void fillBytes() {
73 | bytes = Bytes.allocateDirect(size).unchecked(true);
74 | for (int i = 0; i < bytes.capacity(); i += 8) {
75 | bytes.writeLong(i, num += 0x1111111111111111L);
76 | }
77 | bytes.writePosition(bytes.capacity());
78 | }
79 | @Benchmark
80 | public long vanillaHash() {
81 | return OptimisedBytesStoreHash.INSTANCE.applyAsLong(bytes);
82 | }
83 | @Benchmark
84 | public long city11Hash() {
85 | return city_1_1.hashMemory(bytes.address(bytes.readPosition()), bytes.readRemaining());
86 | }
87 | @Benchmark
88 | public long murmur3Hash() {
89 | return murmur_3.hashMemory(bytes.address(bytes.readPosition()), bytes.readRemaining());
90 | }
91 | @Benchmark
92 | public long xx39Hash() {
93 | return xx_r39.hashMemory(bytes.address(bytes.readPosition()), bytes.readRemaining());
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MaskHashScore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | import net.openhft.chronicle.bytes.NativeBytes;
20 |
21 | import java.security.SecureRandom;
22 | import java.util.Arrays;
23 | import java.util.HashSet;
24 | import java.util.Set;
25 |
26 | /**
27 | * Created by peter on 22/08/15.
28 | */
29 | public class MaskHashScore {
30 | /**
31 | * This test looks at how many collision you get in the lower bits.
32 | * It generates 8K hashes, for 8Kbit input and look at at the lower 14 bits (for 16K values)
33 | * The ideal is 8K unique hashes after mask.
34 | */
35 | public static double score(AddressWrapper wrapper) {
36 | int runs = 2000;
37 |
38 | int bits = 8192;
39 | int mask = bits * 2 - 1;
40 | int[] collisions = new int[runs];
41 | for (int t = 0; t < runs; t++) {
42 | Set maskedhashs = new HashSet<>();
43 | byte[] init = new byte[bits / 8];
44 | NativeBytes b = NativeBytes.nativeBytes(init.length);
45 | SecureRandom rand = new SecureRandom();
46 | rand.nextBytes(init);
47 | // low bit count test
48 | if (t % 2 == 0) {
49 | byte[] init2 = new byte[bits / 8];
50 | rand.nextBytes(init2);
51 | for (int i = 0; i < init.length; i++)
52 | init[i] &= init2[i];
53 | }
54 | wrapper.setAddress(b.address(0), b.realCapacity());
55 |
56 | b.clear();
57 | b.write(init);
58 | for (int i = 0; i < bits; i++) {
59 | int index = i >> 6 << 3;
60 | long prev = b.readLong(index);
61 | b.writeLong(index, prev ^ (1L << i));
62 | b.readLimit(bits / 8);
63 | maskedhashs.add((int) (wrapper.hash() & mask));
64 | b.writeLong(index, prev);
65 | }
66 | collisions[t] = (bits - maskedhashs.size());
67 | }
68 | Arrays.sort(collisions);
69 | int score = collisions[runs * 99 / 100];
70 | System.out.println("Mask of Hash: 99%tile collisions: " + score);
71 | return score;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/measures/src/main/java/net/openhft/chronicle/algorithms/measures/OrtogonalBitsScore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algorithms.measures;
18 |
19 | import net.openhft.chronicle.bytes.NativeBytes;
20 |
21 | import java.security.SecureRandom;
22 | import java.util.Arrays;
23 |
24 | /**
25 | * Created by peter on 21/08/15.
26 | */
27 | public class OrtogonalBitsScore {
28 | public static long score(AddressWrapper wrapper) {
29 | int runs = 1000;
30 | long[] scores = new long[runs];
31 | long[] times = new long[runs];
32 | for (int t = 0; t < runs; t++) {
33 | long[] hashs = new long[8192];
34 | byte[] init = new byte[hashs.length / 8];
35 | NativeBytes b = NativeBytes.nativeBytes(init.length);
36 | SecureRandom rand = new SecureRandom();
37 | rand.nextBytes(init);
38 | // low bit count test
39 | if (t % 2 == 0) {
40 | byte[] init2 = new byte[hashs.length / 8];
41 | rand.nextBytes(init2);
42 | for (int i = 0; i < init.length; i++)
43 | init[i] &= init2[i];
44 | }
45 | wrapper.setAddress(b.address(0), b.realCapacity());
46 |
47 | b.clear();
48 | b.write(init);
49 | for (int i = 0; i < hashs.length; i++) {
50 | int index = i >> 6 << 3;
51 | long prev = b.readLong(index);
52 | b.writeLong(index, prev ^ (1L << i));
53 | b.readLimit(hashs.length / 8);
54 | long start = System.nanoTime();
55 | hashs[i] = wrapper.hash();
56 | times[t] = System.nanoTime() - start;
57 | b.writeLong(index, prev);
58 | }
59 | long score = 0;
60 | for (int i = 0; i < hashs.length - 1; i++)
61 | for (int j = i + 1; j < hashs.length; j++) {
62 | long diff = hashs[j] ^ hashs[i];
63 | int diffBC = Long.bitCount(diff);
64 | if (diffBC < 18) {
65 | long d = 1L << (17 - diffBC);
66 | score += d;
67 | }
68 | }
69 | scores[t] = score;
70 | }
71 | Arrays.sort(scores);
72 | Arrays.sort(times);
73 | long score = scores[runs * 99 / 100];
74 | long time = times[runs * 99 / 100];
75 | System.out.println("Orthogonal bits: 99%tile score: " + score);
76 | System.out.printf("Speed: The 99%%tile for latency was %.3f us%n", time / 1e3);
77 | return score;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 | 4.0.0
22 |
23 |
24 | net.openhft
25 | java-parent-pom
26 | 1.27ea1
27 |
28 |
29 |
30 | chronicle-algorithms
31 | 2.27ea1-SNAPSHOT
32 | OpenHFT/Chronicle-Algorithms
33 | Chronicle-Algorithms
34 |
35 |
36 |
37 |
38 |
39 | net.openhft
40 | third-party-bom
41 | 3.27ea0
42 | pom
43 | import
44 |
45 |
46 |
47 | net.openhft
48 | chronicle-bom
49 | 2.27ea-SNAPSHOT
50 | pom
51 | import
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | net.openhft
62 | chronicle-core
63 |
64 |
65 |
66 | net.openhft
67 | chronicle-bytes
68 |
69 |
70 |
71 | org.slf4j
72 | slf4j-api
73 |
74 |
75 |
76 | org.jetbrains
77 | annotations
78 |
79 |
80 |
81 |
82 |
83 | junit
84 | junit
85 | test
86 |
87 |
88 |
89 | org.slf4j
90 | slf4j-simple
91 | test
92 |
93 |
94 |
95 | org.mockito
96 | mockito-core
97 | test
98 |
99 |
100 |
101 | com.google.guava
102 | guava-testlib
103 | test
104 |
105 |
106 |
107 |
108 |
109 |
110 | third-party-release
111 | ThirdParty Repository
112 |
113 | https://nexus.chronicle.software/content/repositories/thirdparty/
114 |
115 |
116 | true
117 |
118 |
119 |
120 | chronicle-enterprise-snapshots
121 | Snapshot Repository
122 |
123 | https://nexus.chronicle.software/content/repositories/snapshots
124 |
125 |
126 | true
127 |
128 |
129 |
130 | chronicle-enterprise-release
131 |
132 | https://nexus.chronicle.software/content/repositories/releases
133 |
134 |
135 | true
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | org.apache.maven.plugins
145 | maven-scm-publish-plugin
146 |
147 | ${project.build.directory}/scmpublish/javadoc
148 |
149 | Publishing javadoc for ${project.artifactId}:${project.version}
150 |
151 | ${project.reporting.outputDirectory}
152 | true
153 | scm:git:git@github.com:OpenHFT/Chronicle-Algorithms
154 | gh-pages
155 |
156 |
157 |
158 |
159 |
160 |
161 | scm:git:git@github.com:OpenHFT/Chronicle-Algorithms.git
162 | scm:git:git@github.com:OpenHFT/Chronicle-Algorithms.git
163 | scm:git:git@github.com:OpenHFT/Chronicle-Algorithms.git
164 |
165 | master
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bitset/BitSetAlgorithm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.bitset;
18 |
19 | public interface BitSetAlgorithm {
20 |
21 | long sizeInBytes(long logicalSize);
22 |
23 | long maxLogicalSizeFittingSameSizeInBytes(long logicalSize);
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.bitset;
18 |
19 | import static net.openhft.chronicle.algo.MemoryUnit.BITS;
20 |
21 | enum FlatBitSetAlgorithm implements BitSetAlgorithm {
22 | INSTANCE;
23 |
24 | @Override
25 | public long sizeInBytes(long logicalSize) {
26 | return BITS.toBytes(logicalSize);
27 | }
28 |
29 | @Override
30 | public long maxLogicalSizeFittingSameSizeInBytes(long logicalSize) {
31 | return logicalSize;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bitset/ReusableBitSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.bitset;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public class ReusableBitSet implements BitSet {
22 | protected BitSetFrame frame;
23 | protected Access access;
24 | protected Object handle;
25 | protected long offset;
26 |
27 | public ReusableBitSet(
28 | BitSetFrame frame, Access access, T handle, long offset) {
29 | reuse(frame, access, handle, offset);
30 | }
31 |
32 | public final ReusableBitSet reuse(
33 | BitSetFrame frame, Access access, T handle, long offset) {
34 | this.frame = frame;
35 | @SuppressWarnings("unchecked")
36 | Access access0 = (Access) access;
37 | this.access = access0;
38 | this.handle = handle;
39 | this.offset = offset;
40 | return this;
41 | }
42 |
43 | public void setOffset(long offset) {
44 | this.offset = offset;
45 | }
46 |
47 | @Override
48 | public void flip(long bitIndex) {
49 | frame.flip(access, handle, offset, bitIndex);
50 | }
51 |
52 | @Override
53 | public void flipRange(long fromIndex, long toIndex) {
54 | frame.flipRange(access, handle, offset, fromIndex, toIndex);
55 | }
56 |
57 | @Override
58 | public void set(long bitIndex) {
59 | frame.set(access, handle, offset, bitIndex);
60 | }
61 |
62 | @Override
63 | public boolean setIfClear(long bitIndex) {
64 | return frame.setIfClear(access, handle, offset, bitIndex);
65 | }
66 |
67 | @Override
68 | public boolean clearIfSet(long bitIndex) {
69 | return frame.clearIfSet(access, handle, offset, bitIndex);
70 | }
71 |
72 | @Override
73 | public void setRange(long fromIndex, long toIndex) {
74 | frame.setRange(access, handle, offset, fromIndex, toIndex);
75 | }
76 |
77 | @Override
78 | public boolean isRangeSet(long fromIndex, long toIndex) {
79 | return frame.isRangeSet(access, handle, offset, fromIndex, toIndex);
80 | }
81 |
82 | @Override
83 | public void setAll() {
84 | frame.setAll(access, handle, offset);
85 | }
86 |
87 | @Override
88 | public void clear(long bitIndex) {
89 | frame.clear(access, handle, offset, bitIndex);
90 | }
91 |
92 | @Override
93 | public void clearRange(long fromIndex, long toIndex) {
94 | frame.clearRange(access, handle, offset, fromIndex, toIndex);
95 | }
96 |
97 | @Override
98 | public boolean isRangeClear(long fromIndex, long toIndex) {
99 | return frame.isRangeClear(access, handle, offset, fromIndex, toIndex);
100 | }
101 |
102 | @Override
103 | public void clearAll() {
104 | frame.clearAll(access, handle, offset);
105 | }
106 |
107 | @Override
108 | public boolean get(long bitIndex) {
109 | return frame.get(access, handle, offset, bitIndex);
110 | }
111 |
112 | @Override
113 | public long nextSetBit(long fromIndex) {
114 | return frame.nextSetBit(access, handle, offset, fromIndex);
115 | }
116 |
117 | @Override
118 | public long nextClearBit(long fromIndex) {
119 | return frame.nextClearBit(access, handle, offset, fromIndex);
120 | }
121 |
122 | @Override
123 | public long previousSetBit(long fromIndex) {
124 | return frame.previousSetBit(access, handle, offset, fromIndex);
125 | }
126 |
127 | @Override
128 | public long previousClearBit(long fromIndex) {
129 | return frame.previousClearBit(access, handle, offset, fromIndex);
130 | }
131 |
132 | @Override
133 | public long logicalSize() {
134 | return frame.logicalSize();
135 | }
136 |
137 | @Override
138 | public long cardinality() {
139 | return frame.cardinality(access, handle, offset);
140 | }
141 |
142 | @Override
143 | public long setNextClearBit(long fromIndex) {
144 | return frame.setNextClearBit(access, handle, offset, fromIndex);
145 | }
146 |
147 | @Override
148 | public long clearNextSetBit(long fromIndex) {
149 | return frame.clearNextSetBit(access, handle, offset, fromIndex);
150 | }
151 |
152 | @Override
153 | public long setPreviousClearBit(long fromIndex) {
154 | return frame.setPreviousClearBit(access, handle, offset, fromIndex);
155 | }
156 |
157 | @Override
158 | public long clearPreviousSetBit(long fromIndex) {
159 | return frame.clearPreviousSetBit(access, handle, offset, fromIndex);
160 | }
161 |
162 | @Override
163 | public long setNextNContinuousClearBits(long fromIndex, int numberOfBits) {
164 | return frame.setNextNContinuousClearBits(access, handle, offset, fromIndex, numberOfBits);
165 | }
166 |
167 | @Override
168 | public long clearNextNContinuousSetBits(long fromIndex, int numberOfBits) {
169 | return frame.clearNextNContinuousSetBits(access, handle, offset, fromIndex, numberOfBits);
170 | }
171 |
172 | @Override
173 | public long setPreviousNContinuousClearBits(long fromIndex, int numberOfBits) {
174 | return frame.setPreviousNContinuousClearBits(access, handle, offset,
175 | fromIndex, numberOfBits);
176 | }
177 |
178 | @Override
179 | public long clearPreviousNContinuousSetBits(long fromIndex, int numberOfBits) {
180 | return frame.clearPreviousNContinuousSetBits(access, handle, offset,
181 | fromIndex, numberOfBits);
182 | }
183 |
184 | @Override
185 | public Bits setBits() {
186 | return new Bits(frame.setBits());
187 | }
188 |
189 | protected class Bits implements BitSet.Bits {
190 | protected BitSetFrame.Bits frameBits;
191 |
192 | public Bits(BitSetFrame.Bits frameBits) {
193 | this.frameBits = frameBits;
194 | }
195 |
196 | @Override
197 | public BitSet.Bits reset() {
198 | frameBits.reset(access, handle, offset);
199 | return this;
200 | }
201 |
202 | @Override
203 | public long next() {
204 | return frameBits.next(access, handle, offset);
205 | }
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/Access.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.bytes.BytesStore;
20 | import net.openhft.chronicle.bytes.RandomDataInput;
21 |
22 | import java.nio.ByteBuffer;
23 |
24 | public interface Access extends ReadAccess, WriteAccess {
25 |
26 | static Access nativeAccess() {
27 | return NativeAccess.instance();
28 | }
29 |
30 | static Access checkedByteBufferAccess() {
31 | return ByteBufferAccess.INSTANCE;
32 | }
33 |
34 | @SuppressWarnings("unchecked")
35 | static , U> Access checkedBytesStoreAccess() {
36 | return (Access) BytesAccesses.Full.INSTANCE;
37 | }
38 |
39 | static ReadAccess checkedRandomDataInputAccess() {
40 | return BytesAccesses.RandomDataInputReadAccessEnum.INSTANCE;
41 | }
42 |
43 | static void copy(final ReadAccess sourceAccess,
44 | final S source,
45 | final long sourceOffset,
46 | final WriteAccess targetAccess,
47 | final T target,
48 | final long targetOffset,
49 | final long len) {
50 | if (targetAccess == sourceAccess && target == source && targetOffset == sourceOffset)
51 | return;
52 | long i = 0;
53 | while (len - i >= 8L) {
54 | targetAccess.writeLong(target, targetOffset + i, sourceAccess.readLong(source, sourceOffset + i));
55 | i += 8L;
56 | }
57 | if (len - i >= 4L) {
58 | targetAccess.writeInt(target, targetOffset + i, sourceAccess.readInt(source, sourceOffset + i));
59 | i += 4L;
60 | }
61 | if (len - i >= 2L) {
62 | targetAccess.writeShort(target, targetOffset + i, sourceAccess.readShort(source, sourceOffset + i));
63 | i += 2L;
64 | }
65 | if (i < len) {
66 | targetAccess.writeByte(target, targetOffset + i, sourceAccess.readByte(source, sourceOffset + i));
67 | }
68 | }
69 |
70 | static boolean equivalent(final ReadAccess access1,
71 | final T handle1,
72 | final long offset1,
73 | final ReadAccess access2,
74 | final U handle2,
75 | final long offset2,
76 | final long len) {
77 | long i = 0;
78 | while (len - i >= 8L) {
79 | if (access1.readLong(handle1, offset1 + i) != access2.readLong(handle2, offset2 + i))
80 | return false;
81 | i += 8L;
82 | }
83 | if (len - i >= 4L) {
84 | if (access1.readInt(handle1, offset1 + i) != access2.readInt(handle2, offset2 + i))
85 | return false;
86 | i += 4L;
87 | }
88 | if (len - i >= 2L) {
89 | if (access1.readShort(handle1, offset1 + i) != access2.readShort(handle2, offset2 + i))
90 | return false;
91 | i += 2L;
92 | }
93 | if (i < len) {
94 | return access1.readByte(handle1, offset1 + i) == access2.readByte(handle2, offset2 + i);
95 | }
96 | return true;
97 | }
98 |
99 | /**
100 | * Default implementation: throws {@code UnsupportedOperationException}.
101 | */
102 | boolean compareAndSwapInt(T handle, long offset, int expected, int value);
103 |
104 | /**
105 | * Default implementation: throws {@code UnsupportedOperationException}.
106 | */
107 | boolean compareAndSwapLong(T handle, long offset, long expected, long value);
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/AccessCommon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.nio.ByteOrder;
20 |
21 | @FunctionalInterface
22 | interface AccessCommon {
23 | ByteOrder byteOrder(T handle);
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/Accessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.bytes.BytesStore;
20 |
21 | import java.nio.ByteBuffer;
22 | import java.nio.ByteOrder;
23 |
24 | public interface Accessor> {
25 |
26 | @SuppressWarnings("unchecked")
27 | static , U> Accessor.Full checkedBytesStoreAccessor() {
28 | return (Accessor.Full) BytesAccessors.Generic.INSTANCE;
29 | }
30 |
31 | static Accessor.Full uncheckedByteBufferAccessor(
32 | ByteBuffer buffer) {
33 | return ByteBufferAccessor.unchecked(buffer);
34 | }
35 |
36 | static Accessor.Full booleanArrayAccessor() {
37 | return ArrayAccessors.Boolean.INSTANCE;
38 | }
39 |
40 | static Accessor.Full byteArrayAccessor() {
41 | return ArrayAccessors.Byte.INSTANCE;
42 | }
43 |
44 | static Accessor.Full charArrayAccessor() {
45 | return ArrayAccessors.Char.INSTANCE;
46 | }
47 |
48 | static Accessor.Full shortArrayAccessor() {
49 | return ArrayAccessors.Short.INSTANCE;
50 | }
51 |
52 | static Accessor.Full intArrayAccessor() {
53 | return ArrayAccessors.Int.INSTANCE;
54 | }
55 |
56 | static Accessor.Full longArrayAccessor() {
57 | return ArrayAccessors.Long.INSTANCE;
58 | }
59 |
60 | @SuppressWarnings("unchecked")
61 | static Accessor.Read stringAccessor() {
62 | return (Read) CharSequenceAccessor.stringAccessor;
63 | }
64 |
65 | static Accessor.Read checkedNativeCharSequenceAccessor() {
66 | return CharSequenceAccessor.nativeCharSequenceAccessor();
67 | }
68 |
69 | static Accessor.Read checkedCharSequenceAccess(ByteOrder order) {
70 | return order == ByteOrder.LITTLE_ENDIAN ? CharSequenceAccessor.LITTLE_ENDIAN :
71 | CharSequenceAccessor.BIG_ENDIAN;
72 | }
73 |
74 | /**
75 | * Returns {@code Access} for the given source.
76 | *
77 | * @return {@code Access} for the given source
78 | */
79 | A access();
80 |
81 | /**
82 | * Returns handle for {@code Access} to the given source.
83 | *
84 | * @param source the source
85 | * @return handle for {@code Access} to the given source
86 | */
87 | T handle(S source);
88 |
89 | /**
90 | * Convert index in the source domain to {@code Access} offset.
91 | *
92 | * @param source the source
93 | * @param index index in the source type domain
94 | * @return offset for {@code Access}, corresponding to the given index
95 | */
96 | long offset(S source, long index);
97 |
98 | /**
99 | * Convert size (length) in the source domain to size in bytes.
100 | *
101 | * The default implementation returns the given {@code size} back, i. e. assuming
102 | * byte-indexed source.
103 | *
104 | * @param size size (length) in the source type domain
105 | * @return number of bytes, corresponding to the given size in the source type domain
106 | */
107 | default long size(long size) {
108 | return size;
109 | }
110 |
111 | interface Read extends Accessor> {
112 | }
113 |
114 | interface Full extends Accessor> {
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/ArrayAccessors.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import static net.openhft.chronicle.core.UnsafeMemory.MEMORY;
20 |
21 | final class ArrayAccessors {
22 |
23 | static final long BYTE_BASE;
24 | private static final long BOOLEAN_BASE;
25 | private static final long CHAR_BASE;
26 | private static final long SHORT_BASE;
27 | private static final long INT_BASE;
28 | private static final long LONG_BASE;
29 |
30 | static {
31 | try {
32 | BOOLEAN_BASE = MEMORY.arrayBaseOffset(boolean[].class);
33 | BYTE_BASE = MEMORY.arrayBaseOffset(byte[].class);
34 | CHAR_BASE = MEMORY.arrayBaseOffset(char[].class);
35 | SHORT_BASE = MEMORY.arrayBaseOffset(short[].class);
36 | INT_BASE = MEMORY.arrayBaseOffset(int[].class);
37 | LONG_BASE = MEMORY.arrayBaseOffset(long[].class);
38 |
39 | } catch (Exception e) {
40 | throw new AssertionError(e);
41 | }
42 | }
43 |
44 | private ArrayAccessors() {
45 | }
46 |
47 | enum Boolean implements Accessor.Full {
48 | INSTANCE;
49 |
50 | @Override
51 | public Access access() {
52 | return NativeAccess.instance();
53 | }
54 |
55 | @Override
56 | public boolean[] handle(boolean[] source) {
57 | return source;
58 | }
59 |
60 | @Override
61 | public long offset(boolean[] source, long index) {
62 | return BOOLEAN_BASE + index;
63 | }
64 | }
65 |
66 | enum Byte implements Accessor.Full {
67 | INSTANCE;
68 |
69 | @Override
70 | public Access access() {
71 | return NativeAccess.instance();
72 | }
73 |
74 | @Override
75 | public byte[] handle(byte[] source) {
76 | return source;
77 | }
78 |
79 | @Override
80 | public long offset(byte[] source, long index) {
81 | return BYTE_BASE + index;
82 | }
83 | }
84 |
85 | enum Char implements Accessor.Full {
86 | INSTANCE;
87 |
88 | @Override
89 | public Access access() {
90 | return NativeAccess.instance();
91 | }
92 |
93 | @Override
94 | public char[] handle(char[] source) {
95 | return source;
96 | }
97 |
98 | @Override
99 | public long offset(char[] source, long index) {
100 | return CHAR_BASE + (index * 2L);
101 | }
102 |
103 | @Override
104 | public long size(long size) {
105 | return size * 2L;
106 | }
107 | }
108 |
109 | enum Short implements Accessor.Full {
110 | INSTANCE;
111 |
112 | @Override
113 | public Access access() {
114 | return NativeAccess.instance();
115 | }
116 |
117 | @Override
118 | public short[] handle(short[] source) {
119 | return source;
120 | }
121 |
122 | @Override
123 | public long offset(short[] source, long index) {
124 | return SHORT_BASE + (index * 2L);
125 | }
126 |
127 | @Override
128 | public long size(long size) {
129 | return size * 2L;
130 | }
131 | }
132 |
133 | enum Int implements Accessor.Full {
134 | INSTANCE;
135 |
136 | @Override
137 | public Access access() {
138 | return NativeAccess.instance();
139 | }
140 |
141 | @Override
142 | public int[] handle(int[] source) {
143 | return source;
144 | }
145 |
146 | @Override
147 | public long offset(int[] source, long index) {
148 | return INT_BASE + (index * 4L);
149 | }
150 |
151 | @Override
152 | public long size(long size) {
153 | return size * 4L;
154 | }
155 | }
156 |
157 | enum Long implements Accessor.Full {
158 | INSTANCE;
159 |
160 | @Override
161 | public Access access() {
162 | return NativeAccess.instance();
163 | }
164 |
165 | @Override
166 | public long[] handle(long[] source) {
167 | return source;
168 | }
169 |
170 | @Override
171 | public long offset(long[] source, long index) {
172 | return LONG_BASE + (index * 8L);
173 | }
174 |
175 | @Override
176 | public long size(long size) {
177 | return size * 8L;
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/ByteBufferAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.nio.ByteBuffer;
20 | import java.nio.ByteOrder;
21 |
22 | final class ByteBufferAccess implements Access {
23 | public static final ByteBufferAccess INSTANCE = new ByteBufferAccess();
24 |
25 | private ByteBufferAccess() {
26 | }
27 |
28 | @Override
29 | public byte readByte(ByteBuffer buffer, long offset) {
30 | return buffer.get((int) offset);
31 | }
32 |
33 | @Override
34 | public short readShort(ByteBuffer buffer, long offset) {
35 | return buffer.getShort((int) offset);
36 | }
37 |
38 | @Override
39 | public char readChar(ByteBuffer buffer, long offset) {
40 | return buffer.getChar((int) offset);
41 | }
42 |
43 | @Override
44 | public int readInt(ByteBuffer buffer, long offset) {
45 | return buffer.getInt((int) offset);
46 | }
47 |
48 | @Override
49 | public long readLong(ByteBuffer buffer, long offset) {
50 | return buffer.getLong((int) offset);
51 | }
52 |
53 | @Override
54 | public float readFloat(ByteBuffer buffer, long offset) {
55 | return buffer.getFloat((int) offset);
56 | }
57 |
58 | @Override
59 | public double readDouble(ByteBuffer buffer, long offset) {
60 | return buffer.getDouble((int) offset);
61 | }
62 |
63 | @Override
64 | public void writeByte(ByteBuffer buffer, long offset, byte i8) {
65 | buffer.put((int) offset, i8);
66 | }
67 |
68 | @Override
69 | public void writeShort(ByteBuffer buffer, long offset, short i) {
70 | buffer.putShort((int) offset, i);
71 | }
72 |
73 | @Override
74 | public void writeChar(ByteBuffer buffer, long offset, char c) {
75 | buffer.putChar((int) offset, c);
76 | }
77 |
78 | @Override
79 | public void writeInt(ByteBuffer buffer, long offset, int i) {
80 | buffer.putInt((int) offset, i);
81 | }
82 |
83 | @Override
84 | public void writeLong(ByteBuffer buffer, long offset, long i) {
85 | buffer.putLong((int) offset, i);
86 | }
87 |
88 | @Override
89 | public void writeFloat(ByteBuffer buffer, long offset, float d) {
90 | buffer.putFloat((int) offset, d);
91 | }
92 |
93 | @Override
94 | public void writeDouble(ByteBuffer buffer, long offset, double d) {
95 | buffer.putDouble((int) offset, d);
96 | }
97 |
98 | @Override
99 | public ByteOrder byteOrder(ByteBuffer buffer) {
100 | return buffer.order();
101 | }
102 |
103 | @Override
104 | public boolean compareAndSwapInt(ByteBuffer handle, long offset, int expected, int value) {
105 | throw new UnsupportedOperationException("todo");
106 | }
107 |
108 | @Override
109 | public boolean compareAndSwapLong(ByteBuffer handle, long offset, long expected, long value) {
110 | throw new UnsupportedOperationException("todo");
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/ByteBufferAccessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.nio.ByteBuffer;
20 |
21 | import static net.openhft.chronicle.core.UnsafeMemory.MEMORY;
22 |
23 | interface ByteBufferAccessor extends Accessor.Full {
24 |
25 | static ByteBufferAccessor> unchecked(ByteBuffer buffer) {
26 | return buffer.isDirect() ? Direct.INSTANCE : Heap.INSTANCE;
27 | }
28 |
29 | static ByteBufferAccessor checked() {
30 | return Generic.INSTANCE;
31 | }
32 |
33 | enum Direct implements ByteBufferAccessor {
34 | INSTANCE;
35 |
36 | @Override
37 | public Access access() {
38 | return NativeAccess.instance();
39 | }
40 |
41 | @Override
42 | public Void handle(ByteBuffer buffer) {
43 | return null;
44 | }
45 |
46 | @Override
47 | public long offset(ByteBuffer buffer, long bufferIndex) {
48 | return MEMORY.address(buffer) + bufferIndex;
49 | }
50 | }
51 |
52 | enum Heap implements ByteBufferAccessor {
53 | INSTANCE;
54 |
55 | @Override
56 | public Access access() {
57 | return NativeAccess.instance();
58 | }
59 |
60 | @Override
61 | public byte[] handle(ByteBuffer buffer) {
62 | return buffer.array();
63 | }
64 |
65 | @Override
66 | public long offset(ByteBuffer buffer, long bufferIndex) {
67 | return ArrayAccessors.BYTE_BASE + buffer.arrayOffset() + bufferIndex;
68 | }
69 | }
70 |
71 | enum Generic implements ByteBufferAccessor {
72 | INSTANCE;
73 |
74 | @Override
75 | public Access access() {
76 | return ByteBufferAccess.INSTANCE;
77 | }
78 |
79 | @Override
80 | public ByteBuffer handle(ByteBuffer buffer) {
81 | return buffer;
82 | }
83 |
84 | @Override
85 | public long offset(ByteBuffer buffer, long bufferIndex) {
86 | return bufferIndex;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/BytesAccesses.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.bytes.BytesStore;
20 | import net.openhft.chronicle.bytes.RandomDataInput;
21 |
22 | import java.nio.ByteOrder;
23 |
24 | final class BytesAccesses {
25 |
26 | private BytesAccesses() {
27 | }
28 |
29 | enum RandomDataInputReadAccessEnum implements RandomDataInputAccess {
30 | INSTANCE
31 | }
32 |
33 | static class Full, U> implements RandomDataInputAccess,
34 | RandomDataOutputAccess, Access {
35 |
36 | static final Full, ?> INSTANCE = new Full<>();
37 |
38 | @Override
39 | public boolean compareAndSwapInt(B handle, long offset, int expected, int value) {
40 | return handle.compareAndSwapInt(offset, expected, value);
41 | }
42 |
43 | @Override
44 | public boolean compareAndSwapLong(B handle, long offset, long expected, long value) {
45 | return handle.compareAndSwapLong(offset, expected, value);
46 | }
47 |
48 | @Override
49 | public ByteOrder byteOrder(B handle) {
50 | return handle.byteOrder();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/BytesAccessors.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.bytes.BytesStore;
20 |
21 | final class BytesAccessors {
22 |
23 | private BytesAccessors() {
24 | }
25 |
26 | static class Generic> implements Accessor.Full {
27 |
28 | static final Generic> INSTANCE = new Generic<>();
29 |
30 | @SuppressWarnings("unchecked")
31 | @Override
32 | public Access access() {
33 | return (Access) BytesAccesses.Full.INSTANCE;
34 | }
35 |
36 | @Override
37 | public S handle(S source) {
38 | return source;
39 | }
40 |
41 | @Override
42 | public long offset(S source, long index) {
43 | return index;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/CharSequenceAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.nio.ByteOrder;
20 |
21 | import static java.nio.ByteOrder.BIG_ENDIAN;
22 | import static java.nio.ByteOrder.LITTLE_ENDIAN;
23 |
24 | abstract class CharSequenceAccess implements ReadAccess {
25 |
26 | private CharSequenceAccess() {
27 | }
28 |
29 | private static CharSequenceAccess charSequenceAccess(ByteOrder order) {
30 | return order == LITTLE_ENDIAN ?
31 | LittleEndianCharSequenceAccess.INSTANCE :
32 | BigEndianCharSequenceAccess.INSTANCE;
33 | }
34 |
35 | private static int ix(long offset) {
36 | return (int) (offset >> 1);
37 | }
38 |
39 | private static long getLong(CharSequence input, long offset,
40 | int char0Off, int char1Off, int char2Off, int char3Off) {
41 | int base = ix(offset);
42 | long char0 = input.charAt(base + char0Off);
43 | long char1 = input.charAt(base + char1Off);
44 | long char2 = input.charAt(base + char2Off);
45 | long char3 = input.charAt(base + char3Off);
46 | return char0 | (char1 << 16) | (char2 << 32) | (char3 << 48);
47 | }
48 |
49 | private static long getUnsignedInt(CharSequence input, long offset,
50 | int char0Off, int char1Off) {
51 | int base = ix(offset);
52 | long char0 = input.charAt(base + char0Off);
53 | long char1 = input.charAt(base + char1Off);
54 | return char0 | (char1 << 16);
55 | }
56 |
57 | private static int getUnsignedByte(CharSequence input, long offset, int shift) {
58 | return (input.charAt(ix(offset)) >> shift) & 0xFF;
59 | }
60 |
61 | @Override
62 | public int readInt(CharSequence input, long offset) {
63 | return (int) readUnsignedInt(input, offset);
64 | }
65 |
66 | @Override
67 | public int readUnsignedShort(CharSequence input, long offset) {
68 | return input.charAt(ix(offset));
69 | }
70 |
71 | @Override
72 | public short readShort(CharSequence input, long offset) {
73 | return (short) input.charAt(ix(offset));
74 | }
75 |
76 | @Override
77 | public byte readByte(CharSequence input, long offset) {
78 | return (byte) readUnsignedByte(input, offset);
79 | }
80 |
81 | static class LittleEndianCharSequenceAccess extends CharSequenceAccess {
82 | static final CharSequenceAccess INSTANCE = new LittleEndianCharSequenceAccess();
83 |
84 | private LittleEndianCharSequenceAccess() {
85 | }
86 |
87 | @Override
88 | public long readLong(CharSequence input, long offset) {
89 | return getLong(input, offset, 0, 1, 2, 3);
90 | }
91 |
92 | @Override
93 | public long readUnsignedInt(CharSequence input, long offset) {
94 | return getUnsignedInt(input, offset, 0, 1);
95 | }
96 |
97 | @Override
98 | public int readUnsignedByte(CharSequence input, long offset) {
99 | return getUnsignedByte(input, offset, ((int) offset & 1) << 3);
100 | }
101 |
102 | @Override
103 | public ByteOrder byteOrder(CharSequence input) {
104 | return LITTLE_ENDIAN;
105 | }
106 | }
107 |
108 | static class BigEndianCharSequenceAccess extends CharSequenceAccess {
109 | static final CharSequenceAccess INSTANCE = new BigEndianCharSequenceAccess();
110 |
111 | private BigEndianCharSequenceAccess() {
112 | }
113 |
114 | @Override
115 | public long readLong(CharSequence input, long offset) {
116 | return getLong(input, offset, 3, 2, 1, 0);
117 | }
118 |
119 | @Override
120 | public long readUnsignedInt(CharSequence input, long offset) {
121 | return getUnsignedInt(input, offset, 1, 0);
122 | }
123 |
124 | @Override
125 | public int readUnsignedByte(CharSequence input, long offset) {
126 | return getUnsignedByte(input, offset, (((int) offset & 1) ^ 1) << 3);
127 | }
128 |
129 | @Override
130 | public ByteOrder byteOrder(CharSequence input) {
131 | return BIG_ENDIAN;
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/CharSequenceAccessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.core.Jvm;
20 |
21 | import java.nio.ByteOrder;
22 |
23 | abstract class CharSequenceAccessor
24 | implements Accessor.Read {
25 |
26 | static final Accessor.Read super String, ?> stringAccessor;
27 | static final CharSequenceAccessor LITTLE_ENDIAN = new CharSequenceAccessor() {
28 | @Override
29 | public ReadAccess access() {
30 | return CharSequenceAccess.LittleEndianCharSequenceAccess.INSTANCE;
31 | }
32 | };
33 | static final CharSequenceAccessor BIG_ENDIAN = new CharSequenceAccessor() {
34 | @Override
35 | public ReadAccess access() {
36 | return CharSequenceAccess.BigEndianCharSequenceAccess.INSTANCE;
37 | }
38 | };
39 |
40 | static {
41 | if (Jvm.isJava9Plus())
42 | stringAccessor = HotSpotStringAccessor.JAVA9PLUS;
43 | else
44 | stringAccessor = HotSpotStringAccessor.JAVA8;
45 | }
46 |
47 | private CharSequenceAccessor() {
48 | }
49 |
50 | static CharSequenceAccessor nativeCharSequenceAccessor() {
51 | return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
52 | }
53 |
54 | @Override
55 | public CharSequence handle(CharSequence source) {
56 | return source;
57 | }
58 |
59 | @Override
60 | public long offset(CharSequence source, long index) {
61 | return index * 2L;
62 | }
63 |
64 | @Override
65 | public long size(long size) {
66 | return size * 2L;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/HotSpotStringAccessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.lang.reflect.Field;
20 |
21 | import static net.openhft.chronicle.core.UnsafeMemory.MEMORY;
22 |
23 | final class HotSpotStringAccessor implements Accessor.Read {
24 | public static final HotSpotStringAccessor JAVA8 = new HotSpotStringAccessor<>();
25 | public static final HotSpotStringAccessor JAVA9PLUS = new HotSpotStringAccessor<>();
26 |
27 | private static final long valueOffset;
28 |
29 | static {
30 | try {
31 | Field valueField = String.class.getDeclaredField("value");
32 | valueOffset = MEMORY.objectFieldOffset(valueField);
33 | } catch (NoSuchFieldException e) {
34 | throw new AssertionError(e);
35 | }
36 | }
37 |
38 | private HotSpotStringAccessor() {
39 | }
40 |
41 | @Override
42 | public ReadAccess access() {
43 | return NativeAccess.instance();
44 | }
45 |
46 | @SuppressWarnings("unchecked")
47 | @Override
48 | public T handle(String source) {
49 | return (T) MEMORY.getObject(source, valueOffset);
50 | }
51 |
52 | @Override
53 | public long offset(String source, long index) {
54 | return ArrayAccessors.Char.INSTANCE.offset(null, index);
55 | }
56 |
57 | @Override
58 | public long size(long size) {
59 | return size * 2L;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/NativeAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.nio.ByteOrder;
20 |
21 | import static net.openhft.chronicle.core.UnsafeMemory.MEMORY;
22 |
23 | public final class NativeAccess implements Access {
24 |
25 | private static final NativeAccess INSTANCE = new NativeAccess<>();
26 |
27 | private NativeAccess() {
28 | }
29 |
30 | @SuppressWarnings("unchecked")
31 | public static NativeAccess instance() {
32 | //noinspection unchecked
33 | return (NativeAccess) INSTANCE;
34 | }
35 |
36 | @Override
37 | public byte readByte(T handle, long offset) {
38 | return MEMORY.readByte(handle, offset);
39 | }
40 |
41 | @Override
42 | public short readShort(T handle, long offset) {
43 | return MEMORY.readShort(handle, offset);
44 | }
45 |
46 | @Override
47 | public char readChar(T handle, long offset) {
48 | return (char) MEMORY.readShort(handle, offset);
49 | }
50 |
51 | @Override
52 | public int readInt(T handle, long offset) {
53 | return MEMORY.readInt(handle, offset);
54 | }
55 |
56 | @Override
57 | public long readLong(T handle, long offset) {
58 | return MEMORY.readLong(handle, offset);
59 | }
60 |
61 | @Override
62 | public float readFloat(T handle, long offset) {
63 | return MEMORY.readFloat(handle, offset);
64 | }
65 |
66 | @Override
67 | public double readDouble(T handle, long offset) {
68 | return MEMORY.readDouble(handle, offset);
69 | }
70 |
71 | @Override
72 | public int readVolatileInt(T handle, long offset) {
73 | return MEMORY.readVolatileInt(handle, offset);
74 | }
75 |
76 | @Override
77 | public long readVolatileLong(T handle, long offset) {
78 | return MEMORY.readVolatileLong(handle, offset);
79 | }
80 |
81 | @Override
82 | public void writeByte(T handle, long offset, byte i8) {
83 | MEMORY.writeByte(handle, offset, i8);
84 | }
85 |
86 | @Override
87 | public void writeShort(T handle, long offset, short i) {
88 | MEMORY.writeShort(handle, offset, i);
89 | }
90 |
91 | @Override
92 | public void writeChar(T handle, long offset, char c) {
93 | MEMORY.writeShort(handle, offset, (short) c);
94 | }
95 |
96 | @Override
97 | public void writeInt(T handle, long offset, int i) {
98 | MEMORY.writeInt(handle, offset, i);
99 | }
100 |
101 | @Override
102 | public void writeOrderedInt(T handle, long offset, int i) {
103 | MEMORY.writeOrderedInt(handle, offset, i);
104 | }
105 |
106 | @Override
107 | public void writeLong(T handle, long offset, long i) {
108 | MEMORY.writeLong(handle, offset, i);
109 | }
110 |
111 | @Override
112 | public void writeOrderedLong(T handle, long offset, long i) {
113 | MEMORY.writeOrderedLong(handle, offset, i);
114 | }
115 |
116 | @Override
117 | public void writeFloat(T handle, long offset, float d) {
118 | MEMORY.writeFloat(handle, offset, d);
119 | }
120 |
121 | @Override
122 | public void writeDouble(T handle, long offset, double d) {
123 | MEMORY.writeDouble(handle, offset, d);
124 | }
125 |
126 | @Override
127 | public boolean compareAndSwapInt(T handle, long offset, int expected, int value) {
128 | return MEMORY.compareAndSwapInt(handle, offset, expected, value);
129 | }
130 |
131 | @Override
132 | public boolean compareAndSwapLong(T handle, long offset, long expected, long value) {
133 | return MEMORY.compareAndSwapLong(handle, offset, expected, value);
134 | }
135 |
136 | @Override
137 | public ByteOrder byteOrder(T handle) {
138 | return ByteOrder.nativeOrder();
139 | }
140 |
141 | @Override
142 | public void writeBytes(T handle, long offset, long len, byte b) {
143 | MEMORY.setMemory(handle, offset, len, b);
144 | }
145 |
146 | @Override
147 | public void zeroOut(T handle, long offset, long len) {
148 | MEMORY.setMemory(handle, offset, len, (byte) 0);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.bytes.RandomDataInput;
20 |
21 | import java.nio.ByteOrder;
22 |
23 | interface RandomDataInputAccess extends ReadAccess {
24 | @Override
25 | default boolean readBoolean(S handle, long offset) {
26 | return handle.readBoolean(offset);
27 | }
28 |
29 | @Override
30 | default byte readByte(S handle, long offset) {
31 | return handle.readByte(offset);
32 | }
33 |
34 | @Override
35 | default int readUnsignedByte(S handle, long offset) {
36 | return handle.readUnsignedByte(offset);
37 | }
38 |
39 | @Override
40 | default short readShort(S handle, long offset) {
41 | return handle.readShort(offset);
42 | }
43 |
44 | @Override
45 | default int readUnsignedShort(S handle, long offset) {
46 | return handle.readUnsignedShort(offset);
47 | }
48 |
49 | @Override
50 | default int readInt(S handle, long offset) {
51 | return handle.readInt(offset);
52 | }
53 |
54 | @Override
55 | default long readUnsignedInt(S handle, long offset) {
56 | return handle.readUnsignedInt(offset);
57 | }
58 |
59 | @Override
60 | default long readLong(S handle, long offset) {
61 | return handle.readLong(offset);
62 | }
63 |
64 | @Override
65 | default float readFloat(S handle, long offset) {
66 | return handle.readFloat(offset);
67 | }
68 |
69 | @Override
70 | default double readDouble(S handle, long offset) {
71 | return handle.readDouble(offset);
72 | }
73 |
74 | @Override
75 | default String printable(S handle, long offset) {
76 | return handle.printable(offset);
77 | }
78 |
79 | @Override
80 | default int readVolatileInt(S handle, long offset) {
81 | return handle.readVolatileInt(offset);
82 | }
83 |
84 | @Override
85 | default long readVolatileLong(S handle, long offset) {
86 | return handle.readVolatileLong(offset);
87 | }
88 |
89 | @Override
90 | default ByteOrder byteOrder(S handle) {
91 | return handle.byteOrder();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.bytes.RandomDataOutput;
20 |
21 | import java.nio.ByteOrder;
22 |
23 | interface RandomDataOutputAccess>
24 | extends WriteAccess {
25 | @Override
26 | default void writeByte(R handle, long offset, int i) {
27 | handle.writeByte(offset, i);
28 | }
29 |
30 | @Override
31 | default void writeUnsignedByte(R handle, long offset, int i) {
32 | handle.writeUnsignedByte(offset, i);
33 | }
34 |
35 | @Override
36 | default void writeBoolean(R handle, long offset, boolean flag) {
37 | handle.writeBoolean(offset, flag);
38 | }
39 |
40 | @Override
41 | default void writeUnsignedShort(R handle, long offset, int i) {
42 | handle.writeUnsignedShort(offset, i);
43 | }
44 |
45 | @Override
46 | default void writeUnsignedInt(R handle, long offset, long i) {
47 | handle.writeUnsignedInt(offset, i);
48 | }
49 |
50 | @Override
51 | default void writeByte(R handle, long offset, byte i8) {
52 | handle.writeByte(offset, i8);
53 | }
54 |
55 | @Override
56 | default void writeShort(R handle, long offset, short i) {
57 | handle.writeShort(offset, i);
58 | }
59 |
60 | @Override
61 | default void writeInt(R handle, long offset, int i) {
62 | handle.writeInt(offset, i);
63 | }
64 |
65 | @Override
66 | default void writeOrderedInt(R handle, long offset, int i) {
67 | handle.writeOrderedInt(offset, i);
68 | }
69 |
70 | @Override
71 | default void writeLong(R handle, long offset, long i) {
72 | handle.writeLong(offset, i);
73 | }
74 |
75 | @Override
76 | default void writeOrderedLong(R handle, long offset, long i) {
77 | handle.writeOrderedLong(offset, i);
78 | }
79 |
80 | @Override
81 | default void writeFloat(R handle, long offset, float d) {
82 | handle.writeFloat(offset, d);
83 | }
84 |
85 | @Override
86 | default void writeDouble(R handle, long offset, double d) {
87 | handle.writeDouble(offset, d);
88 | }
89 |
90 | @Override
91 | default ByteOrder byteOrder(R handle) {
92 | return handle.byteOrder();
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/ReadAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | public interface ReadAccess extends AccessCommon {
20 |
21 | static ReadAccess zeros() {
22 | return ZeroAccess.INSTANCE;
23 | }
24 |
25 | default boolean readBoolean(T handle, long offset) {
26 | return readByte(handle, offset) != 0;
27 | }
28 |
29 | byte readByte(T handle, long offset);
30 |
31 | default int readUnsignedByte(T handle, long offset) {
32 | return readByte(handle, offset) & 0xFF;
33 | }
34 |
35 | short readShort(T handle, long offset);
36 |
37 | default int readUnsignedShort(T handle, long offset) {
38 | return readShort(handle, offset) & 0xFFFF;
39 | }
40 |
41 | default char readChar(T handle, long offset) {
42 | return (char) readShort(handle, offset);
43 | }
44 |
45 | int readInt(T handle, long offset);
46 |
47 | default long readUnsignedInt(T handle, long offset) {
48 | return readInt(handle, offset) & 0xFFFFFFFFL;
49 | }
50 |
51 | long readLong(T handle, long offset);
52 |
53 | /**
54 | * Default implementation: {@code Float.intBitsToFloat(readInt(handle, offset))}.
55 | */
56 | default float readFloat(T handle, long offset) {
57 | return Float.intBitsToFloat(readInt(handle, offset));
58 | }
59 |
60 | /**
61 | * Default implementation: {@code Double.longBitsToDouble(readLong(handle, offset))}.
62 | */
63 | default double readDouble(T handle, long offset) {
64 | return Double.longBitsToDouble(readLong(handle, offset));
65 | }
66 |
67 | default String printable(T handle, long offset) {
68 | int b = readUnsignedByte(handle, offset);
69 | if (b == 0)
70 | return "\u0660";
71 | else if (b < 21)
72 | return String.valueOf((char) (b + 0x2487));
73 | else
74 | return String.valueOf((char) b);
75 | }
76 |
77 | /**
78 | * Default implementation: throws {@code UnsupportedOperationException}.
79 | */
80 | default int readVolatileInt(T handle, long offset) {
81 | throw new UnsupportedOperationException();
82 | }
83 |
84 | /**
85 | * Default implementation: throws {@code UnsupportedOperationException}.
86 | */
87 | default long readVolatileLong(T handle, long offset) {
88 | throw new UnsupportedOperationException();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/WriteAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import net.openhft.chronicle.core.Maths;
20 |
21 | interface WriteAccess extends AccessCommon {
22 | default void writeByte(T handle, long offset, int i) {
23 | writeByte(handle, offset, Maths.toInt8(i));
24 | }
25 |
26 | default void writeUnsignedByte(T handle, long offset, int i) {
27 | writeByte(handle, offset, (byte) Maths.toUInt8(i));
28 | }
29 |
30 | default void writeBoolean(T handle, long offset, boolean flag) {
31 | writeByte(handle, offset, flag ? 'Y' : 0);
32 | }
33 |
34 | default void writeUnsignedShort(T handle, long offset, int i) {
35 | writeShort(handle, offset, (short) Maths.toUInt16(i));
36 | }
37 |
38 | default void writeChar(T handle, long offset, char c) {
39 | writeShort(handle, offset, (short) c);
40 | }
41 |
42 | default void writeUnsignedInt(T handle, long offset, long i) {
43 | writeInt(handle, offset, (int) Maths.toUInt32(i));
44 | }
45 |
46 | void writeByte(T handle, long offset, byte i8);
47 |
48 | void writeShort(T handle, long offset, short i);
49 |
50 | void writeInt(T handle, long offset, int i);
51 |
52 | /**
53 | * Default implementation: throws {@code UnsupportedOperationException}.
54 | */
55 | default void writeOrderedInt(T handle, long offset, int i) {
56 | throw new UnsupportedOperationException();
57 | }
58 |
59 | void writeLong(T handle, long offset, long i);
60 |
61 | /**
62 | * Default implementation: throws {@code UnsupportedOperationException}.
63 | */
64 | default void writeOrderedLong(T handle, long offset, long i) {
65 | throw new UnsupportedOperationException();
66 | }
67 |
68 | void writeFloat(T handle, long offset, float d);
69 |
70 | void writeDouble(T handle, long offset, double d);
71 |
72 | default void writeBytes(T handle, long offset, long len, byte b) {
73 | char c;
74 | int i;
75 | long l;
76 | switch (b) {
77 | case 0:
78 | zeroOut(handle, offset, len);
79 | return;
80 | case -1:
81 | c = Character.MAX_VALUE;
82 | i = -1;
83 | l = -1;
84 | break;
85 | default:
86 | int ub = b & 0xFF;
87 | int ic = ub | (ub << 8);
88 | c = (char) ic;
89 | i = ic | (ic << 16);
90 | long ui = i & 0xFFFFFFFFL;
91 | l = ui | (ui << 32);
92 | }
93 | long index = 0;
94 | while (len - index >= 8L) {
95 | writeLong(handle, offset + index, l);
96 | index += 8L;
97 | }
98 | if (len - index >= 4L) {
99 | writeInt(handle, offset + index, i);
100 | index += 4L;
101 | }
102 | if (len - index >= 2L) {
103 | writeChar(handle, offset + index, c);
104 | index += 2L;
105 | }
106 | if (index < len)
107 | writeByte(handle, offset + index, b);
108 | }
109 |
110 | default void zeroOut(T handle, long offset, long len) {
111 | long index = 0;
112 | while (len - index >= 8L) {
113 | writeLong(handle, offset + index, 0L);
114 | index += 8L;
115 | }
116 | if (len - index >= 4L) {
117 | writeInt(handle, offset + index, 0);
118 | index += 4L;
119 | }
120 | if (len - index >= 2L) {
121 | writeChar(handle, offset + index, (char) 0);
122 | index += 2L;
123 | }
124 | if (index < len)
125 | writeByte(handle, offset + index, (byte) 0);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/bytes/ZeroAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015-2020 chronicle.software
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU Lesser General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU Lesser General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package net.openhft.chronicle.algo.bytes;
18 |
19 | import java.nio.ByteOrder;
20 |
21 | enum ZeroAccess implements ReadAccess {
22 | INSTANCE;
23 |
24 | @Override
25 | public boolean readBoolean(Void handle, long offset) {
26 | return false;
27 | }
28 |
29 | @Override
30 | public byte readByte(Void handle, long offset) {
31 | return 0;
32 | }
33 |
34 | @Override
35 | public int readUnsignedByte(Void handle, long offset) {
36 | return 0;
37 | }
38 |
39 | @Override
40 | public short readShort(Void handle, long offset) {
41 | return 0;
42 | }
43 |
44 | @Override
45 | public int readUnsignedShort(Void handle, long offset) {
46 | return 0;
47 | }
48 |
49 | @Override
50 | public char readChar(Void handle, long offset) {
51 | return 0;
52 | }
53 |
54 | @Override
55 | public int readInt(Void handle, long offset) {
56 | return 0;
57 | }
58 |
59 | @Override
60 | public long readUnsignedInt(Void handle, long offset) {
61 | return 0;
62 | }
63 |
64 | @Override
65 | public long readLong(Void handle, long offset) {
66 | return 0;
67 | }
68 |
69 | @Override
70 | public float readFloat(Void handle, long offset) {
71 | return 0;
72 | }
73 |
74 | @Override
75 | public double readDouble(Void handle, long offset) {
76 | return 0;
77 | }
78 |
79 | @Override
80 | public String printable(Void handle, long offset) {
81 | return "\u0660";
82 | }
83 |
84 | @Override
85 | public int readVolatileInt(Void handle, long offset) {
86 | return 0;
87 | }
88 |
89 | @Override
90 | public long readVolatileLong(Void handle, long offset) {
91 | return 0;
92 | }
93 |
94 | @Override
95 | public ByteOrder byteOrder(Void handle) {
96 | return ByteOrder.nativeOrder();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/hashing/MurmurHash_3.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.hashing;
18 |
19 | import net.openhft.chronicle.algo.bytes.ReadAccess;
20 |
21 | import static java.lang.Long.reverseBytes;
22 | import static java.nio.ByteOrder.LITTLE_ENDIAN;
23 | import static net.openhft.chronicle.algo.hashing.LongHashFunction.NATIVE_LITTLE_ENDIAN;
24 |
25 | /**
26 | * Derived from https://github.com/google/guava/blob/fa95e381e665d8ee9639543b99ed38020c8de5ef
27 | * /guava/src/com/google/common/hash/Murmur3_128HashFunction.java
28 | */
29 | class MurmurHash_3 {
30 | private static final MurmurHash_3 INSTANCE = new MurmurHash_3();
31 |
32 | private static final MurmurHash_3 NATIVE_MURMUR = NATIVE_LITTLE_ENDIAN ?
33 | MurmurHash_3.INSTANCE : BigEndian.INSTANCE;
34 |
35 | private static final long C1 = 0x87c37b91114253d5L;
36 | private static final long C2 = 0x4cf5ad432745937fL;
37 |
38 | private MurmurHash_3() {
39 | }
40 |
41 | private static long finalize(long length, long h1, long h2) {
42 | h1 ^= length;
43 | h2 ^= length;
44 |
45 | h1 += h2;
46 | h2 += h1;
47 |
48 | h1 = fmix64(h1);
49 | h2 = fmix64(h2);
50 |
51 | h1 += h2;
52 | return h1;
53 | }
54 |
55 | private static long fmix64(long k) {
56 | k ^= k >>> 33;
57 | k *= 0xff51afd7ed558ccdL;
58 | k ^= k >>> 33;
59 | k *= 0xc4ceb9fe1a85ec53L;
60 | k ^= k >>> 33;
61 | return k;
62 | }
63 |
64 | private static long mixK1(long k1) {
65 | k1 *= C1;
66 | k1 = Long.rotateLeft(k1, 31);
67 | k1 *= C2;
68 | return k1;
69 | }
70 |
71 | private static long mixK2(long k2) {
72 | k2 *= C2;
73 | k2 = Long.rotateLeft(k2, 33);
74 | k2 *= C1;
75 | return k2;
76 | }
77 |
78 | public static LongHashFunction asLongHashFunctionWithoutSeed() {
79 | return AsLongHashFunction.INSTANCE;
80 | }
81 |
82 | public static LongHashFunction asLongHashFunctionWithSeed(long seed) {
83 | return new AsLongHashFunctionSeeded(seed);
84 | }
85 |
86 | long fetch64(ReadAccess access, T in, long off) {
87 | return access.readLong(in, off);
88 | }
89 |
90 | int fetch32(ReadAccess access, T in, long off) {
91 | return access.readInt(in, off);
92 | }
93 |
94 | long toLittleEndian(long v) {
95 | return v;
96 | }
97 |
98 | int toLittleEndian(int v) {
99 | return v;
100 | }
101 |
102 | int toLittleEndianShort(int unsignedShort) {
103 | return unsignedShort;
104 | }
105 |
106 | @SuppressWarnings("fallthrough")
107 | public long hash(long seed, T input, ReadAccess access, long offset, long length) {
108 | long h1 = seed;
109 | long h2 = seed;
110 | long remaining = length;
111 | while (remaining >= 16L) {
112 | long k1 = fetch64(access, input, offset);
113 | long k2 = fetch64(access, input, offset + 8L);
114 | offset += 16L;
115 | remaining -= 16L;
116 | h1 ^= mixK1(k1);
117 |
118 | h1 = Long.rotateLeft(h1, 27);
119 | h1 += h2;
120 | h1 = h1 * 5L + 0x52dce729L;
121 |
122 | h2 ^= mixK2(k2);
123 |
124 | h2 = Long.rotateLeft(h2, 31);
125 | h2 += h1;
126 | h2 = h2 * 5L + 0x38495ab5L;
127 | }
128 | if (remaining > 0L) {
129 | long k1 = 0L;
130 | long k2 = 0L;
131 | switch ((int) remaining) {
132 | case 15:
133 | k2 ^= ((long) access.readUnsignedByte(input, offset + 14L)) << 48;//fall through
134 | case 14:
135 | k2 ^= ((long) access.readUnsignedByte(input, offset + 13L)) << 40;//fall through
136 | case 13:
137 | k2 ^= ((long) access.readUnsignedByte(input, offset + 12L)) << 32;//fall through
138 | case 12:
139 | k2 ^= ((long) access.readUnsignedByte(input, offset + 11L)) << 24;//fall through
140 | case 11:
141 | k2 ^= ((long) access.readUnsignedByte(input, offset + 10L)) << 16;//fall through
142 | case 10:
143 | k2 ^= ((long) access.readUnsignedByte(input, offset + 9L)) << 8; // fall through
144 | case 9:
145 | k2 ^= access.readUnsignedByte(input, offset + 8L); // fall through
146 | case 8:
147 | k1 ^= fetch64(access, input, offset);
148 | break;
149 | case 7:
150 | k1 ^= ((long) access.readUnsignedByte(input, offset + 6L)) << 48;// fall through
151 | case 6:
152 | k1 ^= ((long) access.readUnsignedByte(input, offset + 5L)) << 40;// fall through
153 | case 5:
154 | k1 ^= ((long) access.readUnsignedByte(input, offset + 4L)) << 32;// fall through
155 | case 4:
156 | k1 ^= Primitives.unsignedInt(fetch32(access, input, offset));
157 | break;
158 | case 3:
159 | k1 ^= ((long) access.readUnsignedByte(input, offset + 2L)) << 16;// fall through
160 | case 2:
161 | k1 ^= ((long) access.readUnsignedByte(input, offset + 1L)) << 8; // fall through
162 | case 1:
163 | k1 ^= access.readUnsignedByte(input, offset);
164 | case 0:
165 | break;
166 | default:
167 | throw new AssertionError("Should never get here.");
168 | }
169 | h1 ^= mixK1(k1);
170 | h2 ^= mixK2(k2);
171 | }
172 | // This version appears to be working slower
173 |
174 | // if (remaining > 0L) {
175 | // long k1 = 0L;
176 | // long k2 = 0L;
177 | // megaSwitch:
178 | // {
179 | // fetch0_7:
180 | // {
181 | // fetch8_11:
182 | // {
183 | // fetch0_3:
184 | // {
185 | // switch ((int) remaining) {
186 | // case 15:
187 | // k2 ^= ((long) access.readUnsignedByte(input, offset + 14L)) << 48;
188 | // case 14:
189 | // k2 ^= ((long) toLittleEndianShort(
190 | // access.getUnsignedShort(input, offset + 12L))) << 32;
191 | // break fetch8_11;
192 | // case 13:
193 | // k2 ^= ((long) access.readUnsignedByte(input, offset + 12L)) << 32;
194 | // case 12:
195 | // break fetch8_11;
196 | // case 11:
197 | // k2 ^= ((long) access.readUnsignedByte(input, offset + 10L)) << 16;
198 | // case 10:
199 | // k2 ^= (long) toLittleEndianShort(
200 | // access.getUnsignedShort(input, offset + 8L));
201 | // break fetch0_7;
202 | // case 9:
203 | // k2 ^= ((long) access.readUnsignedByte(input, offset + 8L));
204 | // case 8:
205 | // break fetch0_7;
206 | // case 7:
207 | // k1 ^= ((long) access.readUnsignedByte(input, offset + 6L)) << 48;
208 | // case 6:
209 | // k1 ^= ((long) toLittleEndianShort(
210 | // access.getUnsignedShort(input, offset + 4L))) << 32;
211 | // break fetch0_3;
212 | // case 5:
213 | // k1 ^= ((long) access.readUnsignedByte(input, offset + 4L)) << 32;
214 | // case 4:
215 | // break fetch0_3;
216 | // case 3:
217 | // k1 ^= ((long) access.readUnsignedByte(input, offset + 2L)) << 16;
218 | // case 2:
219 | // k1 ^= (long) toLittleEndianShort(
220 | // access.getUnsignedShort(input, offset));
221 | // break megaSwitch;
222 | // case 1:
223 | // k1 ^= ((long) access.readUnsignedByte(input, offset));
224 | // break megaSwitch;
225 | // default:
226 | // throw new AssertionError();
227 | // }
228 | // } // fetch0_3
229 | // k1 ^= unsignedInt(fetch32(access, input, offset));
230 | // break megaSwitch;
231 | // } // fetch8_11
232 | // k2 ^= unsignedInt(fetch32(access, input, offset + 8L));
233 | // } // fetch0_7
234 | // k1 ^= fetch64(access, input, offset);
235 | // } // megaSwitch
236 | //
237 | // h1 ^= mixK1(k1);
238 | // h2 ^= mixK2(k2);
239 | // }
240 | return finalize(length, h1, h2);
241 | }
242 |
243 | private static class BigEndian extends MurmurHash_3 {
244 | private static final BigEndian INSTANCE = new BigEndian();
245 |
246 | private BigEndian() {
247 | }
248 |
249 | @Override
250 | long fetch64(ReadAccess access, T in, long off) {
251 | return reverseBytes(super.fetch64(access, in, off));
252 | }
253 |
254 | @Override
255 | int fetch32(ReadAccess access, T in, long off) {
256 | return Integer.reverseBytes(super.fetch32(access, in, off));
257 | }
258 |
259 | @Override
260 | long toLittleEndian(long v) {
261 | return reverseBytes(v);
262 | }
263 |
264 | @Override
265 | int toLittleEndian(int v) {
266 | return Integer.reverseBytes(v);
267 | }
268 |
269 | @Override
270 | int toLittleEndianShort(int unsignedShort) {
271 | return ((unsignedShort & 0xFF) << 8) | (unsignedShort >> 8);
272 | }
273 | }
274 |
275 | private static class AsLongHashFunction extends LongHashFunction {
276 | public static final AsLongHashFunction INSTANCE = new AsLongHashFunction();
277 | private static final long serialVersionUID = 0L;
278 |
279 | private Object readResolve() {
280 | return INSTANCE;
281 | }
282 |
283 | long seed() {
284 | return 0L;
285 | }
286 |
287 | long hashNativeLong(long nativeLong, long len) {
288 | long h1 = mixK1(nativeLong);
289 | long h2 = 0L;
290 | return MurmurHash_3.finalize(len, h1, h2);
291 | }
292 |
293 | @Override
294 | public long hashLong(long input) {
295 | return hashNativeLong(NATIVE_MURMUR.toLittleEndian(input), 8L);
296 | }
297 |
298 | @Override
299 | public long hashInt(int input) {
300 | return hashNativeLong(Primitives.unsignedInt(NATIVE_MURMUR.toLittleEndian(input)), 4L);
301 | }
302 |
303 | @Override
304 | public long hashShort(short input) {
305 | return hashNativeLong(
306 | NATIVE_MURMUR.toLittleEndianShort(Primitives.unsignedShort(input)), 2L);
307 | }
308 |
309 | @Override
310 | public long hashChar(char input) {
311 | return hashNativeLong(NATIVE_MURMUR.toLittleEndianShort(input), 2L);
312 | }
313 |
314 | @Override
315 | public long hashByte(byte input) {
316 | return hashNativeLong(Primitives.unsignedByte(input), 1L);
317 | }
318 |
319 | @Override
320 | public long hashVoid() {
321 | return 0L;
322 | }
323 |
324 | @Override
325 | public long hash(T input, ReadAccess access, long off, long len) {
326 | long seed = seed();
327 | if (access.byteOrder(input) == LITTLE_ENDIAN) {
328 | return MurmurHash_3.INSTANCE.hash(seed, input, access, off, len);
329 | } else {
330 | return BigEndian.INSTANCE.hash(seed, input, access, off, len);
331 | }
332 | }
333 | }
334 |
335 | private static class AsLongHashFunctionSeeded extends AsLongHashFunction {
336 | private static final long serialVersionUID = 0L;
337 |
338 | private final long seed;
339 | private final transient long voidHash;
340 |
341 | private AsLongHashFunctionSeeded(long seed) {
342 | this.seed = seed;
343 | voidHash = MurmurHash_3.finalize(0L, seed, seed);
344 | }
345 |
346 | @Override
347 | long seed() {
348 | return seed;
349 | }
350 |
351 | @Override
352 | long hashNativeLong(long nativeLong, long len) {
353 | long seed = this.seed;
354 | long h1 = seed ^ mixK1(nativeLong);
355 | long h2 = seed;
356 | return MurmurHash_3.finalize(len, h1, h2);
357 | }
358 |
359 | @Override
360 | public long hashVoid() {
361 | return voidHash;
362 | }
363 | }
364 | }
365 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/hashing/Primitives.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.hashing;
18 |
19 | final class Primitives {
20 |
21 | private Primitives() {
22 | }
23 |
24 | static long unsignedInt(int i) {
25 | return i & 0xFFFFFFFFL;
26 | }
27 |
28 | static int unsignedShort(int s) {
29 | return s & 0xFFFF;
30 | }
31 |
32 | static int unsignedByte(int b) {
33 | return b & 0xFF;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/hashing/XxHash_r39.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.hashing;
18 |
19 | import net.openhft.chronicle.algo.bytes.ReadAccess;
20 |
21 | import static java.nio.ByteOrder.LITTLE_ENDIAN;
22 | import static net.openhft.chronicle.algo.hashing.LongHashFunction.NATIVE_LITTLE_ENDIAN;
23 |
24 | /**
25 | * Adapted version of xxHash implementation from
26 | * https://github.com/Cyan4973/xxHash/releases/tag/r39, which is fully compatible with r40 though.
27 | * This implementation provides endian-independant hash values,
28 | * but it's slower on big-endian platforms.
29 | */
30 | class XxHash_r39 {
31 | private static final XxHash_r39 INSTANCE = new XxHash_r39();
32 | private static final XxHash_r39 NATIVE_XX = NATIVE_LITTLE_ENDIAN ?
33 | XxHash_r39.INSTANCE : BigEndian.INSTANCE;
34 |
35 | // Primes if treated as unsigned
36 | private static final long P1 = -7046029288634856825L;
37 | private static final long P2 = -4417276706812531889L;
38 | private static final long P3 = 1609587929392839161L;
39 | private static final long P4 = -8796714831421723037L;
40 | private static final long P5 = 2870177450012600261L;
41 |
42 | private XxHash_r39() {
43 | }
44 |
45 | private static long finalize(long hash) {
46 | hash ^= hash >>> 33;
47 | hash *= P2;
48 | hash ^= hash >>> 29;
49 | hash *= P3;
50 | hash ^= hash >>> 32;
51 | return hash;
52 | }
53 |
54 | public static LongHashFunction asLongHashFunctionWithoutSeed() {
55 | return AsLongHashFunction.SEEDLESS_INSTANCE;
56 | }
57 |
58 | public static LongHashFunction asLongHashFunctionWithSeed(long seed) {
59 | return new AsLongHashFunctionSeeded(seed);
60 | }
61 |
62 | long fetch64(ReadAccess access, T in, long off) {
63 | return access.readLong(in, off);
64 | }
65 |
66 | // long because of unsigned nature of original algorithm
67 | long fetch32(ReadAccess access, T in, long off) {
68 | return access.readUnsignedInt(in, off);
69 | }
70 |
71 | // int because of unsigned nature of original algorithm
72 | int fetch8(ReadAccess access, T in, long off) {
73 | return access.readUnsignedByte(in, off);
74 | }
75 |
76 | long toLittleEndian(long v) {
77 | return v;
78 | }
79 |
80 | int toLittleEndian(int v) {
81 | return v;
82 | }
83 |
84 | short toLittleEndian(short v) {
85 | return v;
86 | }
87 |
88 | public long xxHash64(long seed, T input, ReadAccess access, long off, long length) {
89 | long hash;
90 | long remaining = length;
91 |
92 | if (remaining >= 32) {
93 | long v1 = seed + P1 + P2;
94 | long v2 = seed + P2;
95 | long v3 = seed;
96 | long v4 = seed - P1;
97 |
98 | do {
99 | v1 += fetch64(access, input, off) * P2;
100 | v1 = Long.rotateLeft(v1, 31);
101 | v1 *= P1;
102 |
103 | v2 += fetch64(access, input, off + 8) * P2;
104 | v2 = Long.rotateLeft(v2, 31);
105 | v2 *= P1;
106 |
107 | v3 += fetch64(access, input, off + 16) * P2;
108 | v3 = Long.rotateLeft(v3, 31);
109 | v3 *= P1;
110 |
111 | v4 += fetch64(access, input, off + 24) * P2;
112 | v4 = Long.rotateLeft(v4, 31);
113 | v4 *= P1;
114 |
115 | off += 32;
116 | remaining -= 32;
117 | } while (remaining >= 32);
118 |
119 | hash = Long.rotateLeft(v1, 1)
120 | + Long.rotateLeft(v2, 7)
121 | + Long.rotateLeft(v3, 12)
122 | + Long.rotateLeft(v4, 18);
123 |
124 | v1 *= P2;
125 | v1 = Long.rotateLeft(v1, 31);
126 | v1 *= P1;
127 | hash ^= v1;
128 | hash = hash * P1 + P4;
129 |
130 | v2 *= P2;
131 | v2 = Long.rotateLeft(v2, 31);
132 | v2 *= P1;
133 | hash ^= v2;
134 | hash = hash * P1 + P4;
135 |
136 | v3 *= P2;
137 | v3 = Long.rotateLeft(v3, 31);
138 | v3 *= P1;
139 | hash ^= v3;
140 | hash = hash * P1 + P4;
141 |
142 | v4 *= P2;
143 | v4 = Long.rotateLeft(v4, 31);
144 | v4 *= P1;
145 | hash ^= v4;
146 | hash = hash * P1 + P4;
147 | } else {
148 | hash = seed + P5;
149 | }
150 | hash += length;
151 |
152 | while (remaining >= 8) {
153 | long k1 = fetch64(access, input, off);
154 | k1 *= P2;
155 | k1 = Long.rotateLeft(k1, 31);
156 | k1 *= P1;
157 | hash ^= k1;
158 | hash = Long.rotateLeft(hash, 27) * P1 + P4;
159 | off += 8;
160 | remaining -= 8;
161 | }
162 | if (remaining >= 4) {
163 | hash ^= fetch32(access, input, off) * P1;
164 | hash = Long.rotateLeft(hash, 23) * P2 + P3;
165 | off += 4;
166 | remaining -= 4;
167 | }
168 | while (remaining != 0) {
169 | hash ^= fetch8(access, input, off) * P5;
170 | hash = Long.rotateLeft(hash, 11) * P1;
171 | --remaining;
172 | ++off;
173 | }
174 | return finalize(hash);
175 | }
176 |
177 | private static class BigEndian extends XxHash_r39 {
178 | private static final BigEndian INSTANCE = new BigEndian();
179 |
180 | private BigEndian() {
181 | }
182 |
183 | @Override
184 | long fetch64(ReadAccess access, T in, long off) {
185 | return Long.reverseBytes(super.fetch64(access, in, off));
186 | }
187 |
188 | @Override
189 | long fetch32(ReadAccess access, T in, long off) {
190 | return Integer.reverseBytes(access.readInt(in, off)) & 0xFFFFFFFFL;
191 | }
192 | // fetch8 is not overloaded, because endianness doesn't matter for single byte
193 |
194 | @Override
195 | long toLittleEndian(long v) {
196 | return Long.reverseBytes(v);
197 | }
198 |
199 | @Override
200 | int toLittleEndian(int v) {
201 | return Integer.reverseBytes(v);
202 | }
203 |
204 | @Override
205 | short toLittleEndian(short v) {
206 | return Short.reverseBytes(v);
207 | }
208 | }
209 |
210 | private static class AsLongHashFunction extends LongHashFunction {
211 | public static final AsLongHashFunction SEEDLESS_INSTANCE = new AsLongHashFunction();
212 | private static final long serialVersionUID = 0L;
213 |
214 | private Object readResolve() {
215 | return SEEDLESS_INSTANCE;
216 | }
217 |
218 | public long seed() {
219 | return 0L;
220 | }
221 |
222 | @Override
223 | public long hashLong(long input) {
224 | input = NATIVE_XX.toLittleEndian(input);
225 | long hash = seed() + P5 + 8;
226 | input *= P2;
227 | input = Long.rotateLeft(input, 31);
228 | input *= P1;
229 | hash ^= input;
230 | hash = Long.rotateLeft(hash, 27) * P1 + P4;
231 | return XxHash_r39.finalize(hash);
232 | }
233 |
234 | @Override
235 | public long hashInt(int input) {
236 | input = NATIVE_XX.toLittleEndian(input);
237 | long hash = seed() + P5 + 4;
238 | hash ^= Primitives.unsignedInt(input) * P1;
239 | hash = Long.rotateLeft(hash, 23) * P2 + P3;
240 | return XxHash_r39.finalize(hash);
241 | }
242 |
243 | @Override
244 | public long hashShort(short input) {
245 | input = NATIVE_XX.toLittleEndian(input);
246 | long hash = seed() + P5 + 2;
247 | hash ^= Primitives.unsignedByte(input) * P5;
248 | hash = Long.rotateLeft(hash, 11) * P1;
249 | hash ^= Primitives.unsignedByte(input >> 8) * P5;
250 | hash = Long.rotateLeft(hash, 11) * P1;
251 | return XxHash_r39.finalize(hash);
252 | }
253 |
254 | @Override
255 | public long hashChar(char input) {
256 | return hashShort((short) input);
257 | }
258 |
259 | @Override
260 | public long hashByte(byte input) {
261 | long hash = seed() + P5 + 1;
262 | hash ^= Primitives.unsignedByte(input) * P5;
263 | hash = Long.rotateLeft(hash, 11) * P1;
264 | return XxHash_r39.finalize(hash);
265 | }
266 |
267 | @Override
268 | public long hashVoid() {
269 | return XxHash_r39.finalize(P5);
270 | }
271 |
272 | @Override
273 | public long hash(T input, ReadAccess access, long off, long len) {
274 | long seed = seed();
275 | if (access.byteOrder(input) == LITTLE_ENDIAN) {
276 | return XxHash_r39.INSTANCE.xxHash64(seed, input, access, off, len);
277 | } else {
278 | return BigEndian.INSTANCE.xxHash64(seed, input, access, off, len);
279 | }
280 | }
281 | }
282 |
283 | private static class AsLongHashFunctionSeeded extends AsLongHashFunction {
284 | private static final long serialVersionUID = 0L;
285 | private final long seed;
286 | private final long voidHash;
287 |
288 | private AsLongHashFunctionSeeded(long seed) {
289 | this.seed = seed;
290 | voidHash = XxHash_r39.finalize(seed + P5);
291 | }
292 |
293 | @Override
294 | public long seed() {
295 | return seed;
296 | }
297 |
298 | @Override
299 | public long hashVoid() {
300 | return voidHash;
301 | }
302 | }
303 | }
304 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/internal/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-2022 chronicle.software
3 | *
4 | * https://chronicle.software
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | /**
20 | * This package and any and all sub-packages contains strictly internal classes for this Chronicle library.
21 | * Internal classes shall never be used directly.
22 | *
23 | * Specifically, the following actions (including, but not limited to) are not allowed
24 | * on internal classes and packages:
25 | *
26 | * Casting to
27 | * Reflection of any kind
28 | * Explicit Serialize/deserialize
29 | *
30 | *
31 | * The classes in this package and any sub-package are subject to
32 | * changes at any time for any reason.
33 | */
34 | package net.openhft.chronicle.algo.internal;
35 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/AbstractReadWriteLockState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | public abstract class AbstractReadWriteLockState implements ReadWriteLockState {
20 |
21 | @Override
22 | public boolean tryLock() {
23 | return tryWriteLock();
24 | }
25 |
26 | @Override
27 | public void unlock() {
28 | writeUnlock();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/AbstractReadWriteLockingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public abstract class AbstractReadWriteLockingStrategy implements ReadWriteLockingStrategy {
22 |
23 | @Override
24 | public boolean tryLock(Access access, T t, long offset) {
25 | return tryWriteLock(access, t, offset);
26 | }
27 |
28 | @Override
29 | public void unlock(Access access, T t, long offset) {
30 | writeUnlock(access, t, offset);
31 | }
32 |
33 | @Override
34 | public boolean isReadLocked(long state) {
35 | return readLockCount(state) > 0;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategies.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 | import net.openhft.chronicle.core.Jvm;
21 |
22 | import java.util.concurrent.TimeUnit;
23 |
24 | public final class AcquisitionStrategies {
25 |
26 | private AcquisitionStrategies() {
27 | }
28 |
29 | public static
30 | AcquisitionStrategy spinLoop(long duration, TimeUnit unit) {
31 | return new SpinLoopAcquisitionStrategy<>(duration, unit);
32 | }
33 |
34 | public static
35 | AcquisitionStrategy spinLoopOrFail(long duration, TimeUnit unit) {
36 | return new SpinLoopOrFailAcquisitionStrategy<>(duration, unit);
37 | }
38 |
39 | public static
40 | AcquisitionStrategy spinLoopRegisteringWaitOrFail(
41 | long duration, TimeUnit unit) {
42 | return new SpinLoopWriteWithWaitsAcquisitionStrategy<>(duration, unit);
43 | }
44 |
45 | private static class SpinLoopAcquisitionStrategy
46 | implements AcquisitionStrategy {
47 | private final long durationNanos;
48 |
49 | private SpinLoopAcquisitionStrategy(long duration, TimeUnit unit) {
50 | durationNanos = unit.toNanos(duration);
51 | }
52 |
53 | @Override
54 | public boolean acquire(TryAcquireOperation super S> operation, S strategy,
55 | Access access, T t, long offset) {
56 | if (operation.tryAcquire(strategy, access, t, offset))
57 | return true;
58 | long deadLineNanos = System.nanoTime() + durationNanos;
59 | beforeLoop(strategy, access, t, offset);
60 | do {
61 | if (operation.tryAcquire(strategy, access, t, offset))
62 | return true;
63 | Jvm.nanoPause();
64 | } while (deadLineNanos - System.nanoTime() >= 0L); // overflow-cautious
65 | afterLoop(strategy, access, t, offset);
66 | return end();
67 | }
68 |
69 | void beforeLoop(S strategy, Access access, T t, long offset) {
70 | }
71 |
72 | void afterLoop(S strategy, Access access, T t, long offset) {
73 | }
74 |
75 | boolean end() {
76 | return false;
77 | }
78 | }
79 |
80 | private static class SpinLoopOrFailAcquisitionStrategy
81 | extends SpinLoopAcquisitionStrategy {
82 |
83 | private SpinLoopOrFailAcquisitionStrategy(long duration, TimeUnit unit) {
84 | super(duration, unit);
85 | }
86 |
87 | @Override
88 | boolean end() {
89 | throw new IllegalStateException("Failed to acquire the lock");
90 | }
91 | }
92 |
93 | private static class SpinLoopWriteWithWaitsAcquisitionStrategy<
94 | S extends ReadWriteWithWaitsLockingStrategy>
95 | extends SpinLoopOrFailAcquisitionStrategy {
96 |
97 | private SpinLoopWriteWithWaitsAcquisitionStrategy(long duration, TimeUnit unit) {
98 | super(duration, unit);
99 | }
100 |
101 | @Override
102 | void beforeLoop(S strategy, Access access, T t, long offset) {
103 | strategy.registerWait(access, t, offset);
104 | }
105 |
106 | @Override
107 | void afterLoop(S strategy, Access access, T t, long offset) {
108 | strategy.deregisterWait(access, t, offset);
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public interface AcquisitionStrategy {
22 |
23 | boolean acquire(
24 | TryAcquireOperation super S> operation, S strategy,
25 | Access access, T t, long offset) throws E;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/LockState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | public interface LockState {
20 |
21 | boolean tryLock();
22 |
23 | void unlock();
24 |
25 | void reset();
26 |
27 | long getState();
28 |
29 | LockingStrategy lockingStrategy();
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/LockingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 | import net.openhft.chronicle.algo.bytes.ReadAccess;
21 |
22 | public interface LockingStrategy {
23 |
24 | boolean tryLock(Access access, T t, long offset);
25 |
26 | void unlock(Access access, T t, long offset);
27 |
28 | void reset(Access access, T t, long offset);
29 |
30 | long resetState();
31 |
32 | long getState(ReadAccess access, T t, long offset);
33 |
34 | boolean isLocked(long state);
35 |
36 | int lockCount(long state);
37 |
38 | String toString(long state);
39 |
40 | int sizeInBytes();
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | public interface ReadWriteLockState extends LockState {
20 |
21 | boolean tryReadLock();
22 |
23 | boolean tryWriteLock();
24 |
25 | boolean tryUpgradeReadToWriteLock();
26 |
27 | void readUnlock();
28 |
29 | void writeUnlock();
30 |
31 | void downgradeWriteToReadLock();
32 |
33 | @Override
34 | ReadWriteLockingStrategy lockingStrategy();
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public interface ReadWriteLockingStrategy extends LockingStrategy {
22 |
23 | boolean tryReadLock(Access access, T t, long offset);
24 |
25 | boolean tryWriteLock(Access access, T t, long offset);
26 |
27 | boolean tryUpgradeReadToWriteLock(Access access, T t, long offset);
28 |
29 | void readUnlock(Access access, T t, long offset);
30 |
31 | void writeUnlock(Access access, T t, long offset);
32 |
33 | void downgradeWriteToReadLock(Access access, T t, long offset);
34 |
35 | boolean isReadLocked(long state);
36 |
37 | boolean isWriteLocked(long state);
38 |
39 | int readLockCount(long state);
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | public interface ReadWriteUpdateLockState extends ReadWriteLockState {
20 |
21 | boolean tryUpdateLock();
22 |
23 | boolean tryUpgradeReadToUpdateLock();
24 |
25 | boolean tryUpgradeUpdateToWriteLock();
26 |
27 | void updateUnlock();
28 |
29 | void downgradeUpdateToReadLock();
30 |
31 | void downgradeWriteToUpdateLock();
32 |
33 | @Override
34 | ReadWriteUpdateLockingStrategy lockingStrategy();
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | /**
22 | * Logic of read-write-update lock state transitions.
23 | *
24 | * Read lock - could be several at the same time.
25 | * Update lock - doesn't block reads, but couldn't be several update locks at the same time
26 | * Write lock - exclusive
27 | */
28 | public interface ReadWriteUpdateLockingStrategy extends ReadWriteLockingStrategy {
29 |
30 | boolean tryUpdateLock(Access access, T t, long offset);
31 |
32 | boolean tryUpgradeReadToUpdateLock(Access access, T t, long offset);
33 |
34 | boolean tryUpgradeUpdateToWriteLock(Access access, T t, long offset);
35 |
36 | void updateUnlock(Access access, T t, long offset);
37 |
38 | void downgradeUpdateToReadLock(Access access, T t, long offset);
39 |
40 | void downgradeWriteToUpdateLock(Access access, T t, long offset);
41 |
42 | boolean isUpdateLocked(long state);
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | public interface ReadWriteUpdateWithWaitsLockState
20 | extends ReadWriteUpdateLockState, ReadWriteWithWaitsLockState {
21 |
22 | boolean tryUpgradeUpdateToWriteLockAndDeregisterWait();
23 |
24 | @Override
25 | ReadWriteUpdateWithWaitsLockingStrategy lockingStrategy();
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public interface ReadWriteUpdateWithWaitsLockingStrategy
22 | extends ReadWriteUpdateLockingStrategy, ReadWriteWithWaitsLockingStrategy {
23 |
24 | boolean tryUpgradeUpdateToWriteLockAndDeregisterWait(
25 | Access access, T t, long offset);
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteWithWaitsLockState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | public interface ReadWriteWithWaitsLockState extends ReadWriteLockState {
20 |
21 | void registerWait();
22 |
23 | void deregisterWait();
24 |
25 | boolean tryWriteLockAndDeregisterWait();
26 |
27 | boolean tryUpgradeReadToWriteLockAndDeregisterWait();
28 |
29 | void resetKeepingWaits();
30 |
31 | @Override
32 | ReadWriteWithWaitsLockingStrategy lockingStrategy();
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteWithWaitsLockingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public interface ReadWriteWithWaitsLockingStrategy extends ReadWriteLockingStrategy {
22 |
23 | void registerWait(Access access, T t, long offset);
24 |
25 | void deregisterWait(Access access, T t, long offset);
26 |
27 | boolean tryWriteLockAndDeregisterWait(Access access, T t, long offset);
28 |
29 | boolean tryUpgradeReadToWriteLockAndDeregisterWait(
30 | Access access, T t, long offset);
31 |
32 | void resetKeepingWaits(Access access, T t, long offset);
33 |
34 | int waitCount(long state);
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public interface TryAcquireOperation {
22 |
23 | boolean tryAcquire(S strategy, Access access, T t, long offset);
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperations.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020 chronicle.software
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package net.openhft.chronicle.algo.locks;
18 |
19 | import net.openhft.chronicle.algo.bytes.Access;
20 |
21 | public final class TryAcquireOperations {
22 |
23 | private static final TryAcquireOperation LOCK =
24 | new TryAcquireOperation() {
25 | @Override
26 | public boolean tryAcquire(LockingStrategy strategy,
27 | Access access, T obj, long offset) {
28 | return strategy.tryLock(access, obj, offset);
29 | }
30 | };
31 | private static final TryAcquireOperation READ_LOCK =
32 | new TryAcquireOperation() {
33 | @Override
34 | public boolean tryAcquire(ReadWriteLockingStrategy strategy,
35 | Access access, T obj, long offset) {
36 | return strategy.tryReadLock(access, obj, offset);
37 | }
38 | };
39 | private static final TryAcquireOperation UPGRADE_READ_TO_WRITE_LOCK =
40 | new TryAcquireOperation() {
41 | @Override
42 | public boolean tryAcquire(ReadWriteLockingStrategy strategy,
43 | Access access, T obj, long offset) {
44 | return strategy.tryUpgradeReadToWriteLock(access, obj, offset);
45 | }
46 | };
47 | private static final TryAcquireOperation WRITE_LOCK =
48 | new TryAcquireOperation() {
49 | @Override
50 | public boolean tryAcquire(ReadWriteLockingStrategy strategy,
51 | Access access, T obj, long offset) {
52 | return strategy.tryWriteLock(access, obj, offset);
53 | }
54 | };
55 | private static final TryAcquireOperation
56 | UPGRADE_READ_TO_WRITE_LOCK_AND_DEREGISTER_WAIT =
57 | new TryAcquireOperation() {
58 | @Override
59 | public boolean tryAcquire(ReadWriteWithWaitsLockingStrategy strategy,
60 | Access access, T obj, long offset) {
61 | return strategy.tryUpgradeReadToWriteLockAndDeregisterWait(access, obj, offset);
62 | }
63 | };
64 | private static final TryAcquireOperation
65 | WRITE_LOCK_AND_DEREGISTER_WAIT =
66 | new TryAcquireOperation() {
67 | @Override
68 | public boolean tryAcquire(ReadWriteWithWaitsLockingStrategy strategy,
69 | Access access, T obj, long offset) {
70 | return strategy.tryWriteLockAndDeregisterWait(access, obj, offset);
71 | }
72 | };
73 | private static final TryAcquireOperation UPDATE_LOCK =
74 | new TryAcquireOperation() {
75 | @Override
76 | public boolean tryAcquire(ReadWriteUpdateLockingStrategy strategy,
77 | Access access, T obj, long offset) {
78 | return strategy.tryUpdateLock(access, obj, offset);
79 | }
80 | };
81 | private static final TryAcquireOperation
82 | UPGRADE_READ_TO_UPDATE_LOCK =
83 | new TryAcquireOperation() {
84 | @Override
85 | public boolean tryAcquire(ReadWriteUpdateLockingStrategy strategy,
86 | Access access, T obj, long offset) {
87 | return strategy.tryUpgradeReadToUpdateLock(access, obj, offset);
88 | }
89 | };
90 | private static final TryAcquireOperation
91 | UPGRADE_UPDATE_TO_WRITE_LOCK =
92 | new TryAcquireOperation() {
93 | @Override
94 | public boolean tryAcquire(ReadWriteUpdateLockingStrategy strategy,
95 | Access access, T obj, long offset) {
96 | return strategy.tryUpgradeUpdateToWriteLock(access, obj, offset);
97 | }
98 | };
99 | private static final TryAcquireOperation
100 | UPGRADE_UPDATE_TO_WRITE_LOCK_AND_DEREGISTER_WAIT =
101 | new TryAcquireOperation() {
102 | @Override
103 | public boolean tryAcquire(ReadWriteUpdateWithWaitsLockingStrategy strategy,
104 | Access access, T obj, long offset) {
105 | return strategy.tryUpgradeUpdateToWriteLockAndDeregisterWait(
106 | access, obj, offset);
107 | }
108 | };
109 |
110 | private TryAcquireOperations() {
111 | }
112 |
113 | public static TryAcquireOperation lock() {
114 | return LOCK;
115 | }
116 |
117 | public static TryAcquireOperation readLock() {
118 | return READ_LOCK;
119 | }
120 |
121 | public static TryAcquireOperation upgradeReadToWriteLock() {
122 | return UPGRADE_READ_TO_WRITE_LOCK;
123 | }
124 |
125 | public static TryAcquireOperation writeLock() {
126 | return WRITE_LOCK;
127 | }
128 |
129 | public static TryAcquireOperation
130 | upgradeReadToWriteLockAndDeregisterWait() {
131 | return UPGRADE_READ_TO_WRITE_LOCK_AND_DEREGISTER_WAIT;
132 | }
133 |
134 | public static TryAcquireOperation
135 | writeLockAndDeregisterWait() {
136 | return WRITE_LOCK_AND_DEREGISTER_WAIT;
137 | }
138 |
139 | public static TryAcquireOperation updateLock() {
140 | return UPDATE_LOCK;
141 | }
142 |
143 | public static TryAcquireOperation upgradeReadToUpdateLock() {
144 | return UPGRADE_READ_TO_UPDATE_LOCK;
145 | }
146 |
147 | public static TryAcquireOperation