├── .gitignore
├── SECURITY.md
├── triemap
├── src
│ ├── main
│ │ └── java
│ │ │ ├── tech
│ │ │ └── pantheon
│ │ │ │ └── triemap
│ │ │ │ ├── Gen.java
│ │ │ │ ├── package-info.java
│ │ │ │ ├── Result.java
│ │ │ │ ├── EntryNode.java
│ │ │ │ ├── PresencePredicate.java
│ │ │ │ ├── Branch.java
│ │ │ │ ├── KeySetIterator.java
│ │ │ │ ├── ImmutableIterator.java
│ │ │ │ ├── VerifyException.java
│ │ │ │ ├── LNode.java
│ │ │ │ ├── ImmutableTrieSet.java
│ │ │ │ ├── DefaultEntry.java
│ │ │ │ ├── LNodeEntry.java
│ │ │ │ ├── MutableTrieSet.java
│ │ │ │ ├── MutableKeySet.java
│ │ │ │ ├── Equivalence.java
│ │ │ │ ├── SNode.java
│ │ │ │ ├── Constants.java
│ │ │ │ ├── AbstractEntry.java
│ │ │ │ ├── MainNode.java
│ │ │ │ ├── MutableEntrySet.java
│ │ │ │ ├── ImmutableKeySet.java
│ │ │ │ ├── TNode.java
│ │ │ │ ├── AbstractEntrySet.java
│ │ │ │ ├── ImmutableEntrySet.java
│ │ │ │ ├── AbstractKeySet.java
│ │ │ │ ├── SerializationProxy.java
│ │ │ │ ├── MutableIterator.java
│ │ │ │ ├── AbstractIterator.java
│ │ │ │ ├── ImmutableTrieMap.java
│ │ │ │ ├── TrieMap.java
│ │ │ │ ├── LNodeEntries.java
│ │ │ │ └── TrieSet.java
│ │ │ └── module-info.java
│ └── test
│ │ └── java
│ │ └── tech
│ │ └── pantheon
│ │ └── triemap
│ │ ├── CNodeTest.java
│ │ ├── VerifyExceptionTest.java
│ │ ├── ConstantsTest.java
│ │ ├── TestConcurrentMapCompute.java
│ │ ├── TestCNodeInsertionIncorrectOrder.java
│ │ ├── INodeTest.java
│ │ ├── TestHashCollisionsRemove.java
│ │ ├── EquivalenceTest.java
│ │ ├── ZeroHashInt.java
│ │ ├── TestHashCollisionsRemoveIterator.java
│ │ ├── TestConcurrentMapMerge.java
│ │ ├── LNodeEntryTest.java
│ │ ├── TestCNodeFlagCollision.java
│ │ ├── TestMultiThreadInserts.java
│ │ ├── SNodeTest.java
│ │ ├── AbstractEntryTest.java
│ │ ├── MutableIteratorTest.java
│ │ ├── ImmutableTrieSetTest.java
│ │ ├── TestSerialization.java
│ │ ├── TNodeTest.java
│ │ ├── TestInsert.java
│ │ ├── SnapshotTest.java
│ │ ├── TestConcurrentMapRemove.java
│ │ ├── TestConcurrentMapPutIfAbsent.java
│ │ ├── ImmutableKeySetTest.java
│ │ ├── ImmutableTrieMapTest.java
│ │ ├── TestConcurrentMapComputeIfAbsent.java
│ │ ├── MutableKeySetTest.java
│ │ ├── LNodeEntriesTest.java
│ │ ├── TestConcurrentMapComputeIfPresent.java
│ │ ├── TestConcurrentMapReplace.java
│ │ ├── TestReadOnlyAndUpdatableIterators.java
│ │ ├── ImmutableEntrySetTest.java
│ │ ├── TestDelete.java
│ │ ├── MutableEntrySetTest.java
│ │ ├── TestMultiThreadAddDelete.java
│ │ ├── TestMapIterator.java
│ │ ├── TestMultiThreadMapIterator.java
│ │ └── TestHashCollisions.java
└── pom.xml
├── .github
└── workflows
│ ├── maven.yml
│ └── codeql.yml
├── dependency-check
└── pom.xml
├── bom
└── pom.xml
├── pt-triemap
└── pom.xml
├── pom.xml
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | **/target
3 | **/target-ide/
4 | .idea
5 | .classpath
6 | .project
7 | .settings
8 | *.iml
9 | *.ipr
10 | *.iws
11 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Versioning
4 |
5 | We follow Semantic Versioning. Our APIs are expected to be extremely stable
6 | and therefore we do not expect to issue a major (2.0.0) version any time soon.
7 |
8 | Minor versions are used when new functionality is introduced, which includes
9 | changing the required baseline Java version.
10 |
11 | Patch versions are issued for bug and security fixes.
12 |
13 | ## Supported Versions
14 |
15 | Versions 1.4.x and 1.3.x (Java 17+), 1.2.x (Java 11+) and 1.1.x (Java 8+) are
16 | currently supported and are receiving any and all relevant bug fixes.
17 |
18 | ## Reporting a Vulnerability
19 |
20 | Please report any discovered or suspected security vulnerabilities to PANTHEON.tech product security team at secalert@pantheon.tech.
21 |
22 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/Gen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | final class Gen {
19 | // Just an identity object
20 | }
21 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2017 PANTHEON.tech, s.r.o. and others.
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 | * Implementation of {@link java.util.concurrent.ConcurrentMap} on top
18 | * of a concurrent hash-trie.
19 | */
20 | @org.osgi.annotation.bundle.Export
21 | package tech.pantheon.triemap;
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/Result.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2020 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | /**
19 | + * Virtual result for lookup/insert methods indicating that the lookup needs to be restarted. This is a faster version
20 | + * of throwing a checked exception to control restart.
21 | */
22 | enum Result {
23 | RESTART;
24 | }
25 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/EntryNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2025 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | /**
19 | * Common glue between {@link DefaultEntry} and {@link SNode}/{@link TNode}. This exists primarily for
20 | * {@link AbstractIterator}'s sake.
21 | */
22 | sealed interface EntryNode extends DefaultEntry permits SNode, TNode {
23 | // Nothing else
24 | }
25 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/PresencePredicate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2017 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | /**
19 | * Presence predicate. These are specialized objects passed down from callers to indicate an assertion about
20 | * whether a mapping is required.
21 | *
22 | * @author Robert Varga
23 | */
24 | enum PresencePredicate {
25 | ABSENT,
26 | PRESENT;
27 | }
28 |
--------------------------------------------------------------------------------
/triemap/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2019 PANTHEON.tech, s.r.o. and others.
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 | * An implementation of {@link java.util.concurrent.ConcurrentMap} based on
18 | * concurrent hash-trie.
19 | */
20 | module tech.pantheon.triemap {
21 | exports tech.pantheon.triemap;
22 |
23 | requires static com.github.spotbugs.annotations;
24 | requires static org.eclipse.jdt.annotation;
25 | requires static org.osgi.annotation.bundle;
26 | }
27 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/Branch.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2025 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | /**
19 | * A Branch: either an {@link INode} or an {@link SNode}.
20 | */
21 | sealed interface Branch permits INode, SNode {
22 | /**
23 | * Return the number of entries for the purposes of {@link CNode#size(ImmutableTrieMap)}.
24 | *
25 | * @param ct TrieMap reference
26 | * @return The actual number of entries
27 | */
28 | int elementSize(ImmutableTrieMap ct);
29 | }
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/KeySetIterator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 | * and is available at http://www.eclipse.org/legal/epl-v10.html
7 | */
8 | package tech.pantheon.triemap;
9 |
10 | import static java.util.Objects.requireNonNull;
11 |
12 | import java.util.Iterator;
13 |
14 | /**
15 | * Iterator given out by {@link AbstractKeySet} implementations.
16 | */
17 | final class KeySetIterator implements Iterator {
18 | private final AbstractIterator delegate;
19 |
20 | KeySetIterator(final AbstractIterator delegate) {
21 | this.delegate = requireNonNull(delegate);
22 | }
23 |
24 | @Override
25 | public boolean hasNext() {
26 | return delegate.hasNext();
27 | }
28 |
29 | @Override
30 | public K next() {
31 | return delegate.next().getKey();
32 | }
33 |
34 | @Override
35 | public void remove() {
36 | delegate.remove();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/CNodeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertThrows;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | class CNodeTest {
24 | @Test
25 | void testTrySize() {
26 | assertEquals(MainNode.NO_SIZE, new CNode<>(new Gen()).trySize());
27 | }
28 |
29 | @Test
30 | void testInvalidElement() {
31 | assertThrows(VerifyException.class, () -> CNode.invalidElement(null));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/ImmutableIterator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2017 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | /**
19 | * Specialized immutable iterator for use with {@link ImmutableEntrySet}.
20 | *
21 | * @author Robert Varga
22 | *
23 | * @param the type of entry keys
24 | * @param the type of entry values
25 | */
26 | final class ImmutableIterator extends AbstractIterator {
27 | ImmutableIterator(final ImmutableTrieMap map) {
28 | super(map);
29 | }
30 |
31 | @Override
32 | DefaultEntry wrapEntry(final DefaultEntry entry) {
33 | return entry;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/VerifyExceptionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertSame;
19 | import static org.junit.jupiter.api.Assertions.assertThrows;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | class VerifyExceptionTest {
24 | @Test
25 | void testThrowIfNullSimple() {
26 | assertThrows(VerifyException.class, () -> VerifyException.throwIfNull(null));
27 | }
28 |
29 | @Test
30 | void testThrowIfNullSame() {
31 | final Object obj = new Object();
32 | assertSame(obj, VerifyException.throwIfNull(obj));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/ConstantsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 | * and is available at http://www.eclipse.org/legal/epl-v10.html
7 | */
8 | package tech.pantheon.triemap;
9 |
10 | import static org.junit.jupiter.api.Assertions.assertEquals;
11 |
12 | import org.junit.jupiter.api.Test;
13 |
14 | class ConstantsTest {
15 | @Test
16 | void hashBits() throws Exception {
17 | // We assume Object.hashCode() is 32 bits
18 | assertEquals(int.class, Object.class.getDeclaredMethod("hashCode").getReturnType());
19 | assertEquals(Integer.SIZE, Constants.HASH_BITS);
20 | }
21 |
22 | @Test
23 | void levelBits() throws Exception {
24 | // CNode.bitmap can store 32 bits
25 | assertEquals(int.class, CNode.class.getDeclaredField("bitmap").getType());
26 | assertEquals((int) (Math.log(Integer.SIZE) / Math.log(2)), Constants.LEVEL_BITS);
27 | }
28 |
29 | @Test
30 | void maxDepth() throws Exception {
31 | assertEquals((int) Math.ceil((double)Constants.HASH_BITS / Constants.LEVEL_BITS), Constants.MAX_DEPTH);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/VerifyException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import org.eclipse.jdt.annotation.NonNull;
19 | import org.eclipse.jdt.annotation.Nullable;
20 |
21 | final class VerifyException extends RuntimeException {
22 | @java.io.Serial
23 | private static final long serialVersionUID = 1L;
24 |
25 | VerifyException(final @NonNull String message) {
26 | super(message);
27 | }
28 |
29 | static @NonNull T throwIfNull(final @Nullable T obj) {
30 | if (obj == null) {
31 | throw new VerifyException("Unexpected null reference");
32 | }
33 | return obj;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestConcurrentMapCompute.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 |
20 | import org.junit.jupiter.api.Test;
21 |
22 | class TestConcurrentMapCompute {
23 | private static final int COUNT = 50 * 1000;
24 |
25 | @Test
26 | void testConcurrentMapCompute() {
27 | final var map = TrieMap.create();
28 |
29 | for (int i = 0; i < COUNT; i++) {
30 | assertEquals(i + " -> null", map.compute(i, (k, v) -> k + " -> " + v));
31 | assertEquals(i + " -> " + i + " -> null", map.compute(i, (k, v) -> k + " -> " + v));
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestCNodeInsertionIncorrectOrder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertSame;
19 |
20 | import org.junit.jupiter.api.Test;
21 |
22 | class TestCNodeInsertionIncorrectOrder {
23 |
24 | @Test
25 | void testCNodeInsertionIncorrectOrder() {
26 | final var map = TrieMap.create();
27 | final Integer z3884 = 3884;
28 | final Integer z4266 = 4266;
29 | map.put(z3884, z3884);
30 | assertSame(z3884, map.get(z3884));
31 |
32 | map.put(z4266, z4266);
33 | assertSame(z3884, map.get(z3884));
34 | assertSame(z4266, map.get(z4266));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/INodeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertThrows;
20 |
21 | import org.junit.jupiter.api.Test;
22 | import tech.pantheon.triemap.INode.FailedGcas;
23 |
24 | class INodeTest {
25 | @Test
26 | void testInvalidElement() {
27 | assertThrows(VerifyException.class, () -> INode.invalidElement(null));
28 | }
29 |
30 | @Test
31 | void testFailedGcasToString() {
32 | final var tnode = new TNode<>(new CNode<>(new Gen()), new Object(), new Object(), 123);
33 | assertEquals("FailedNode(" + tnode + ")", new FailedGcas<>(tnode).toString());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/LNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | final class LNode extends MainNode {
19 | // Internally-linked single list of of entries
20 | final LNodeEntries entries;
21 | final int size;
22 |
23 | LNode(final LNode prev, final LNodeEntries entries, final int size) {
24 | super(prev);
25 | this.entries = entries;
26 | this.size = size;
27 | }
28 |
29 | LNode(final SNode first, final SNode second) {
30 | entries = LNodeEntries.of(first.key(), first.value(), second.key(), second.value());
31 | size = 2;
32 | }
33 |
34 | @Override
35 | int trySize() {
36 | return size;
37 | }
38 |
39 | @Override
40 | int size(final ImmutableTrieMap ct) {
41 | return size;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/ImmutableTrieSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2019 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.util.Collection;
19 |
20 | /**
21 | * An immutable TrieSet. Does not allow modifications.
22 | *
23 | * @param the type of elements maintained by this set
24 | * @author Robert Varga
25 | */
26 | public final class ImmutableTrieSet extends TrieSet {
27 | @java.io.Serial
28 | private static final long serialVersionUID = 1L;
29 |
30 | ImmutableTrieSet(final ImmutableTrieMap map) {
31 | super(map);
32 | }
33 |
34 | @Override
35 | public ImmutableTrieSet immutableSnapshot() {
36 | return this;
37 | }
38 |
39 | @Override
40 | @SuppressWarnings("checkstyle:parameterName")
41 | public boolean addAll(final Collection extends E> c) {
42 | throw new UnsupportedOperationException();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/DefaultEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2017 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.util.Map.Entry;
19 | import org.eclipse.jdt.annotation.NonNull;
20 |
21 | /**
22 | * Our {@link Entry} implementations are immutable by default.
23 | *
24 | * @author Robert Varga
25 | *
26 | * @param the type of key
27 | * @param the type of value
28 | */
29 | sealed interface DefaultEntry extends Entry permits AbstractEntry, EntryNode {
30 |
31 | @NonNull K key();
32 |
33 | @Override
34 | @Deprecated
35 | default K getKey() {
36 | return key();
37 | }
38 |
39 | @NonNull V value();
40 |
41 | @Override
42 | @Deprecated
43 | default V getValue() {
44 | return value();
45 | }
46 |
47 | @Override
48 | default V setValue(final V value) {
49 | throw new UnsupportedOperationException();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/LNodeEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import org.eclipse.jdt.annotation.NonNull;
19 |
20 | /**
21 | * A single entry in {@link LNodeEntries}, implements {@link DefaultEntry} in order to prevent instantiation of objects
22 | * for iteration.
23 | *
24 | * @author Robert Varga
25 | *
26 | * @param the type of key
27 | * @param the type of value
28 | */
29 | abstract sealed class LNodeEntry extends AbstractEntry permits LNodeEntries {
30 | private final @NonNull K key;
31 | private final @NonNull V value;
32 |
33 | LNodeEntry(final @NonNull K key, final @NonNull V value) {
34 | this.key = key;
35 | this.value = value;
36 | }
37 |
38 | @Override
39 | public final K key() {
40 | return key;
41 | }
42 |
43 | @Override
44 | public final V value() {
45 | return value;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/MutableTrieSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2019 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.util.Collection;
19 |
20 | /**
21 | * A mutable TrieSet.
22 | *
23 | * @param the type of elements maintained by this set
24 | * @author Robert Varga
25 | */
26 | public final class MutableTrieSet extends TrieSet {
27 | @java.io.Serial
28 | private static final long serialVersionUID = 0L;
29 |
30 | MutableTrieSet(final MutableTrieMap map) {
31 | super(map);
32 | }
33 |
34 | @Override
35 | public ImmutableTrieSet immutableSnapshot() {
36 | return new ImmutableTrieSet<>(map().immutableSnapshot());
37 | }
38 |
39 | @Override
40 | @SuppressWarnings("checkstyle:parameterName")
41 | public boolean addAll(final Collection extends E> c) {
42 | boolean ret = false;
43 | for (var e : c) {
44 | ret |= add(e);
45 | }
46 | return ret;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestHashCollisionsRemove.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertTrue;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | class TestHashCollisionsRemove {
24 | private static final int COUNT = 50000;
25 |
26 | @Test
27 | void testHashCollisionsRemove() {
28 | final var bt = TrieMap.create();
29 |
30 | for (int j = 0; j < COUNT; j++) {
31 | for (final Object o : TestMultiThreadMapIterator.getObjects(j)) {
32 | bt.put(o, o);
33 | }
34 | }
35 |
36 | for (int j = 0; j < COUNT; j++) {
37 | for (final Object o : TestMultiThreadMapIterator.getObjects(j)) {
38 | bt.remove(o);
39 | }
40 | }
41 |
42 | assertEquals(0, bt.size());
43 | assertTrue(bt.isEmpty());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/EquivalenceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others. All rights reserved.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 | * and is available at http://www.eclipse.org/legal/epl-v10.html
7 | */
8 | package tech.pantheon.triemap;
9 |
10 | import static org.junit.jupiter.api.Assertions.assertEquals;
11 | import static org.junit.jupiter.api.Assertions.assertSame;
12 |
13 | import java.io.ByteArrayInputStream;
14 | import java.io.ByteArrayOutputStream;
15 | import java.io.ObjectInputStream;
16 | import java.io.ObjectOutputStream;
17 | import java.util.HexFormat;
18 | import org.junit.jupiter.api.Test;
19 |
20 | class EquivalenceTest {
21 | @Test
22 | void readResolveWorks() throws Exception {
23 | final var baos = new ByteArrayOutputStream();
24 | try (var oos = new ObjectOutputStream(baos)) {
25 | oos.writeObject(Equivalence.Equals.INSTANCE);
26 | }
27 |
28 | final var bytes = baos.toByteArray();
29 | assertEquals("""
30 | aced000573720028746563682e70616e7468656f6e2e747269656d61702e4571756976616c656e636524457175616c7300000000000\
31 | 0000102000078720021746563682e70616e7468656f6e2e747269656d61702e4571756976616c656e63650000000000000001020000\
32 | 7870""", HexFormat.of().formatHex(bytes));
33 |
34 | try (var ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
35 | assertSame(Equivalence.Equals.INSTANCE, ois.readObject());
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/MutableKeySet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.util.Spliterator;
19 |
20 | /**
21 | * A mutable view of a TrieMap's key set.
22 | *
23 | * @author Robert Varga
24 | *
25 | * @param the type of keys
26 | */
27 | final class MutableKeySet extends AbstractKeySet> {
28 | MutableKeySet(final MutableTrieMap map) {
29 | super(map);
30 | }
31 |
32 | @Override
33 | public KeySetIterator iterator() {
34 | return new KeySetIterator<>(map.iterator());
35 | }
36 |
37 | @Override
38 | public void clear() {
39 | map.clear();
40 | }
41 |
42 | @Override
43 | @SuppressWarnings("checkstyle:parameterName")
44 | public boolean remove(final Object o) {
45 | return map.remove(o) != null;
46 | }
47 |
48 | @Override
49 | int spliteratorCharacteristics() {
50 | return Spliterator.DISTINCT | Spliterator.CONCURRENT | Spliterator.NONNULL;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/ZeroHashInt.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.util.StringJoiner;
19 |
20 | /**
21 | * Utility key/value class which attacks the hasing function, causing all objects to be put into a single bucket.
22 | *
23 | * @author Robert Varga
24 | */
25 | final class ZeroHashInt {
26 | private final int value;
27 |
28 | ZeroHashInt(final int value) {
29 | this.value = value;
30 | }
31 |
32 | @Override
33 | public int hashCode() {
34 | return 0;
35 | }
36 |
37 | @Override
38 | public boolean equals(final Object obj) {
39 | return obj instanceof ZeroHashInt other && value == other.value;
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return new StringJoiner(", ", ZeroHashInt.class.getSimpleName() + "{", "}")
45 | .add("value=" + value)
46 | .add("identity=" + System.identityHashCode(ZeroHashInt.class))
47 | .toString();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestHashCollisionsRemoveIterator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertTrue;
20 |
21 | import java.util.ArrayList;
22 | import org.junit.jupiter.api.Test;
23 |
24 | class TestHashCollisionsRemoveIterator {
25 | private static final int COUNT = 50000;
26 |
27 | @Test
28 | void testHashCollisionsRemoveIterator() {
29 | final var bt = TrieMap.create();
30 | for (int j = 0; j < COUNT; j++) {
31 | bt.put(Integer.valueOf(j), Integer.valueOf(j));
32 | }
33 |
34 | final var list = new ArrayList<>(COUNT);
35 | final var it = bt.entrySet().iterator();
36 | while (it.hasNext()) {
37 | list.add(it.next().getKey());
38 | it.remove();
39 | }
40 |
41 | assertEquals(0, bt.size());
42 | assertTrue(bt.isEmpty());
43 | assertEquals(COUNT, list.size());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/Equivalence.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.io.Serializable;
19 | import org.eclipse.jdt.annotation.NonNullByDefault;
20 |
21 | /**
22 | * Internal equivalence class, similar to com.google.common.base.Equivalence, but explicitly not handling
23 | * nulls. We use equivalence only for keys, which are guaranteed to be non-null.
24 | *
25 | * @author Robert Varga
26 | */
27 | @NonNullByDefault
28 | abstract class Equivalence implements Serializable {
29 | @java.io.Serial
30 | private static final long serialVersionUID = 1L;
31 |
32 | static final class Equals extends Equivalence {
33 | @java.io.Serial
34 | private static final long serialVersionUID = 1L;
35 |
36 | static final Equals INSTANCE = new Equals();
37 |
38 | @Override
39 | Equivalence resolve() {
40 | return INSTANCE;
41 | }
42 | }
43 |
44 | @java.io.Serial
45 | final Object readResolve() {
46 | return resolve();
47 | }
48 |
49 | abstract Equivalence resolve();
50 | }
51 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestConcurrentMapMerge.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.fail;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | class TestConcurrentMapMerge {
24 | private static final int COUNT = 50 * 1000;
25 |
26 | @Test
27 | void testConcurrentMapMergeWhenValueAbsent() {
28 | final var map = TrieMap.create();
29 |
30 | for (int i = 0; i < COUNT; i++) {
31 | final var newVal = Integer.toString(i + 10);
32 | assertEquals(newVal, map.merge(i, newVal, (ov, nv) -> fail("Should not have been called")));
33 | }
34 | }
35 |
36 | @Test
37 | void testConcurrentMapMergeWhenValuePresent() {
38 | final var map = TrieMap.create();
39 |
40 | for (int i = 0; i < COUNT; i++) {
41 | final var newVal = Integer.toString(i + 10);
42 | map.put(i, newVal);
43 | assertEquals(newVal + newVal, map.merge(i, newVal, (ov, nv) -> "" + ov + nv));
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/LNodeEntryTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertThrows;
20 |
21 | import java.util.Map;
22 | import org.junit.jupiter.api.Test;
23 |
24 | class LNodeEntryTest {
25 | private static final String KEY1 = "key1";
26 | private static final String KEY2 = "key2";
27 | private static final String VALUE = "value";
28 |
29 | private final LNodeEntries entry = LNodeEntries.of(KEY1, VALUE, KEY2, VALUE);
30 |
31 | @Test
32 | void testEntryUtil() {
33 | assertEquals(AbstractEntry.hashCode(KEY1, VALUE), entry.hashCode());
34 | assertEquals(AbstractEntry.toString(KEY1, VALUE), entry.toString());
35 |
36 | final var testEntry = Map.entry(KEY1, VALUE);
37 | assertEquals(AbstractEntry.equals(testEntry, KEY1, VALUE), entry.equals(testEntry));
38 | }
39 |
40 | @Test
41 | void testSetValue() {
42 | assertThrows(UnsupportedOperationException.class, () -> entry.setValue(null));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | name: Java CI with Maven
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 | types:
11 | - opened
12 | - synchronize
13 | - reopened
14 |
15 | jobs:
16 | build:
17 |
18 | runs-on: ubuntu-latest
19 |
20 | steps:
21 | - uses: actions/checkout@v4
22 | with:
23 | fetch-depth: 0
24 |
25 | - name: Set up JDK 21
26 | uses: actions/setup-java@v4
27 | with:
28 | java-version: '21'
29 | distribution: 'temurin'
30 |
31 | - name: Cache Maven packages
32 | uses: actions/cache@v4
33 | with:
34 | path: |
35 | ~/.m2/repository/*/*/*
36 | !~/.m2/repository/tech/pantheon/triemap
37 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
38 | restore-keys: ${{ runner.os }}-maven-
39 |
40 | - name: Build with Maven
41 | run: mvn -B -e install --file pom.xml
42 |
43 | - name: Cache SonarCloud packages
44 | uses: actions/cache@v4
45 | with:
46 | path: ~/.sonar/cache
47 | key: ${{ runner.os }}-sonar
48 | restore-keys: ${{ runner.os }}-sonar
49 |
50 | - name: Analyze with SonarCloud
51 | env:
52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
54 | if: env.SONAR_TOKEN != ''
55 | run: mvn -B -e verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=PANTHEONtech_triemap
56 |
57 | # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
58 | #- name: Update dependency graph
59 | # uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6
60 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestCNodeFlagCollision.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertNull;
19 | import static org.junit.jupiter.api.Assertions.assertSame;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | class TestCNodeFlagCollision {
24 | @Test
25 | void testCNodeFlagCollision() {
26 | final var map = TrieMap.create();
27 | final Integer z15169 = 15169;
28 | final Integer z28336 = 28336;
29 |
30 | assertNull(map.get(z15169));
31 | assertNull(map.get(z28336));
32 |
33 | map.put(z15169, z15169);
34 | assertSame(z15169, map.get(z15169));
35 | assertNull(map.get(z28336));
36 |
37 | map.put(z28336, z28336);
38 | assertSame(z15169, map.get(z15169));
39 | assertSame(z28336, map.get(z28336));
40 |
41 | map.remove(z15169);
42 |
43 | assertNull(map.get(z15169));
44 | assertSame(z28336, map.get(z28336));
45 |
46 | map.remove(z28336);
47 |
48 | assertNull(map.get(z15169));
49 | assertNull(map.get(z28336));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/SNode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import org.eclipse.jdt.annotation.NonNull;
19 | import org.eclipse.jdt.annotation.Nullable;
20 |
21 | record SNode(@NonNull K key, @NonNull V value, int hc) implements Branch, EntryNode {
22 | SNode(final TNode tn) {
23 | this(tn.key, tn.value, tn.hc);
24 | }
25 |
26 | @Nullable V lookup(final int otherHc, final K otherKey) {
27 | return matches(otherHc, otherKey) ? value : null;
28 | }
29 |
30 | boolean matches(final int otherHc, final Object otherKey) {
31 | return hc == otherHc && otherKey.equals(key);
32 | }
33 |
34 | @Override
35 | public int elementSize(final ImmutableTrieMap ct) {
36 | return 1;
37 | }
38 |
39 | @Override
40 | public int hashCode() {
41 | return AbstractEntry.hashCode(key, value);
42 | }
43 |
44 | @Override
45 | public boolean equals(final Object obj) {
46 | return AbstractEntry.equals(obj, key, value);
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return AbstractEntry.toString(key, value);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 | pull_request:
7 | # The branches below must be a subset of the branches above
8 | branches: [ "master" ]
9 | schedule:
10 | - cron: '36 20 * * 2'
11 |
12 | jobs:
13 | analyze:
14 | name: Analyze
15 | runs-on: ubuntu-latest
16 | permissions:
17 | actions: read
18 | contents: read
19 | security-events: write
20 |
21 | strategy:
22 | fail-fast: false
23 | matrix:
24 | language: [ 'java' ]
25 |
26 | steps:
27 | - name: Checkout repository
28 | uses: actions/checkout@v3
29 |
30 | # Initializes the CodeQL tools for scanning.
31 | - name: Initialize CodeQL
32 | uses: github/codeql-action/init@v2
33 | with:
34 | languages: ${{ matrix.language }}
35 | # If you wish to specify custom queries, you can do so here or in a config file.
36 | # By default, queries listed here will override any specified in a config file.
37 | # Prefix the list here with "+" to use these queries and those in the config file.
38 |
39 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
40 | # queries: security-extended,security-and-quality
41 |
42 | - name: Set up JDK 17
43 | uses: actions/setup-java@v3
44 | with:
45 | java-version: '17'
46 | distribution: 'temurin'
47 | cache: maven
48 |
49 | - name: Build with Maven
50 | run: mvn --batch-mode --errors --show-version -Pq clean package
51 |
52 | - name: Perform CodeQL Analysis
53 | uses: github/codeql-action/analyze@v2
54 | with:
55 | category: "/language:${{matrix.language}}"
56 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/TestMultiThreadInserts.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2016 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 |
20 | import java.util.concurrent.Executors;
21 | import java.util.concurrent.TimeUnit;
22 | import org.junit.jupiter.api.Test;
23 |
24 | class TestMultiThreadInserts {
25 | @Test
26 | void testMultiThreadInserts() throws InterruptedException {
27 | final int nThreads = 2;
28 | final var es = Executors.newFixedThreadPool(nThreads);
29 | final var bt = TrieMap.create();
30 | for (int i = 0; i < nThreads; i++) {
31 | final int threadNo = i;
32 | es.execute(() -> {
33 | for (int j = 0; j < 500 * 1000; j++) {
34 | if (j % nThreads == threadNo) {
35 | bt.put(Integer.valueOf(j), Integer.valueOf(j));
36 | }
37 | }
38 | });
39 | }
40 |
41 | es.shutdown();
42 | es.awaitTermination(5, TimeUnit.MINUTES);
43 |
44 | for (int j = 0; j < 500 * 1000; j++) {
45 | assertEquals(Integer.valueOf(j), bt.get(Integer.valueOf(j)));
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/SNodeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertSame;
20 |
21 | import java.util.Map;
22 | import org.junit.jupiter.api.Test;
23 |
24 | class SNodeTest {
25 | private static final String KEY = "key";
26 | private static final String VALUE = "value";
27 | private static final int HASH = 1337;
28 |
29 | private final SNode snode = new SNode<>(KEY, VALUE, HASH);
30 |
31 | @Test
32 | void testCopyTombed() {
33 | final var tnode = new TNode<>(new CNode<>(new Gen()), snode);
34 | assertEquals(snode.hashCode(), tnode.hashCode());
35 | assertSame(snode.key(), tnode.key());
36 | assertSame(snode.value(), tnode.value());
37 | }
38 |
39 | @Test
40 | void testEntryUtil() {
41 | assertEquals(AbstractEntry.hashCode(KEY, VALUE), snode.hashCode());
42 | assertEquals(AbstractEntry.toString(KEY, VALUE), snode.toString());
43 |
44 | final var entry = Map.entry(KEY, VALUE);
45 | assertEquals(AbstractEntry.equals(entry, KEY, VALUE), snode.equals(entry));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2017 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | /**
19 | * Various implementation-specific constants shared across classes. Normally we would be deriving both
20 | * {@link #LEVEL_BITS} and {@link #MAX_DEPTH} from {@link #HASH_BITS} and size of {@link CNode#bitmap}, but that would
21 | * mean they would be runtime constants. We really want them to be compile-time constants. Hence we seed them manually
22 | * and assert the constants are correct.
23 | *
24 | * @author Robert Varga
25 | */
26 | final class Constants {
27 | /**
28 | * Size of the hash function, in bits. This corresponds to {@link Object#hashCode()}'s size.
29 | */
30 | static final int HASH_BITS = Integer.SIZE;
31 |
32 | /**
33 | * Number of hash bits consumed in each CNode level. This corresponds to log2(HASH_BITS).
34 | */
35 | static final int LEVEL_BITS = 5;
36 |
37 | /**
38 | * Maximum depth of a TrieMap. Maximum number of CNode levels. This corresponds to
39 | * {@code Math.ceil(HASH_BITS / LEVEL_BITS)}.
40 | */
41 | static final int MAX_DEPTH = 7;
42 |
43 | private Constants() {
44 | // Hidden on purpose
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/triemap/src/main/java/tech/pantheon/triemap/AbstractEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2017 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import java.util.Map.Entry;
19 |
20 | /**
21 | * Base class for things that need to conform to {@link Entry} contract.
22 | *
23 | * @author Robert Varga
24 | */
25 | abstract sealed class AbstractEntry implements DefaultEntry
26 | permits LNodeEntry, MutableIterator.MutableEntry {
27 | @Override
28 | public final int hashCode() {
29 | return hashCode(key(), value());
30 | }
31 |
32 | static final int hashCode(final Object key, final Object value) {
33 | return key.hashCode() ^ value.hashCode();
34 | }
35 |
36 | @Override
37 | public final boolean equals(final Object obj) {
38 | return equals(obj, key(), value());
39 | }
40 |
41 | static final boolean equals(final Object obj, final Object key, final Object value) {
42 | return obj instanceof Entry, ?> entry && key.equals(entry.getKey()) && value.equals(entry.getValue());
43 | }
44 |
45 | @Override
46 | public final String toString() {
47 | return toString(key(), value());
48 | }
49 |
50 | static final String toString(final Object key, final Object value) {
51 | return key + "=" + value;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/AbstractEntryTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertFalse;
20 | import static org.junit.jupiter.api.Assertions.assertTrue;
21 |
22 | import java.util.Map;
23 | import org.junit.jupiter.api.Test;
24 |
25 | class AbstractEntryTest {
26 | @Test
27 | void testEqual() {
28 | final var key = new Object();
29 | final var value = new Object();
30 | assertFalse(AbstractEntry.equals(null, key, value));
31 | assertFalse(AbstractEntry.equals(key, key, value));
32 |
33 | final var entry = Map.entry(key, value);
34 | assertTrue(AbstractEntry.equals(entry, key, value));
35 | assertFalse(AbstractEntry.equals(entry, value, value));
36 | assertFalse(AbstractEntry.equals(entry, key, key));
37 | }
38 |
39 | @Test
40 | void testHash() {
41 | final var key = new Object();
42 | final var value = new Object();
43 | assertEquals(key.hashCode() ^ value.hashCode(), AbstractEntry.hashCode(key, value));
44 | }
45 |
46 | @Test
47 | void testString() {
48 | assertEquals("foo=bar", AbstractEntry.toString("foo", "bar"));
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/MutableIteratorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * (C) Copyright 2018 PANTHEON.tech, s.r.o. and others.
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 | package tech.pantheon.triemap;
17 |
18 | import static org.junit.jupiter.api.Assertions.assertEquals;
19 | import static org.junit.jupiter.api.Assertions.assertThrows;
20 |
21 | import java.util.Map;
22 | import org.junit.jupiter.api.BeforeEach;
23 | import org.junit.jupiter.api.Test;
24 |
25 | class MutableIteratorTest {
26 | private static final String KEY = "key";
27 | private static final String VALUE = "value";
28 |
29 | private MutableIterator it;
30 |
31 | @BeforeEach
32 | void before() {
33 | final var map = TrieMap.create();
34 | map.put(KEY, VALUE);
35 | it = map.iterator();
36 | }
37 |
38 | @Test
39 | void testEntryUtil() {
40 | final var entry = it.next();
41 |
42 | assertEquals(AbstractEntry.hashCode(KEY, VALUE), entry.hashCode());
43 | assertEquals(AbstractEntry.toString(KEY, VALUE), entry.toString());
44 |
45 | final var testEntry = Map.entry(KEY, VALUE);
46 | assertEquals(AbstractEntry.equals(testEntry, KEY, VALUE), entry.equals(entry));
47 | }
48 |
49 | @Test
50 | void testRemoveWithoutNext() {
51 | assertThrows(IllegalStateException.class, () -> it.remove());
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/triemap/src/test/java/tech/pantheon/triemap/ImmutableTrieSetTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 | * and is available at http://www.eclipse.org/legal/epl-v10.html
7 | */
8 | package tech.pantheon.triemap;
9 |
10 | import static org.junit.jupiter.api.Assertions.assertSame;
11 | import static org.junit.jupiter.api.Assertions.assertThrows;
12 |
13 | import java.util.List;
14 | import java.util.function.Predicate;
15 | import org.junit.jupiter.api.Test;
16 |
17 | class ImmutableTrieSetTest {
18 | private final ImmutableTrieSet