Skip to content

Commit 08a7199

Browse files
Merge pull request #4 from WorksApplications/add-traverse
Add traverse()
2 parents 77736ca + 2fd93c4 commit 08a7199

3 files changed

Lines changed: 142 additions & 1 deletion

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.worksap.nlp</groupId>
55
<artifactId>jdartsclone</artifactId>
6-
<version>1.0.2-SNAPSHOT</version>
6+
<version>1.1.0-SNAPSHOT</version>
77
<packaging>jar</packaging>
88
<name>Darts-clone</name>
99

src/main/java/com/worksap/nlp/dartsclone/DoubleArray.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@
3939
*/
4040
public class DoubleArray {
4141

42+
/**
43+
* The result of a traverse operation.
44+
*
45+
* This class contains the result of a traverse, the position of the key,
46+
* and the index of the node after the traverse.
47+
*/
48+
public static class TraverseResult {
49+
/** The result of a traverse */
50+
public int result;
51+
/** the position of the key after a traverse */
52+
public int offset;
53+
/** the node after a traverse */
54+
public int nodePosition;
55+
56+
TraverseResult(int result, int offset, int nodePosition) {
57+
this.result = result;
58+
this.offset = offset;
59+
this.nodePosition = nodePosition;
60+
}
61+
}
62+
4263
private IntBuffer array;
4364
private ByteBuffer buffer;
4465
private int size; // number of elements
@@ -235,6 +256,45 @@ public Iterator<int[]> commonPrefixSearch(byte[] key, int offset) {
235256
return new Itr(key, offset);
236257
}
237258

259+
/**
260+
* Returns the value to which the specified key is mapped by
261+
* traversing the trie from the specified node.
262+
*
263+
* If {@code node} is 0, starts traversing from the root node.
264+
*
265+
* If {@code offset} is not 0, the key is evaluated as the sub array
266+
* removed the first {@code offset} bytes.
267+
*
268+
* Returns -1 as the value if a traverse is failed at the end of the key,
269+
* or -2 at a middle of the key.
270+
*
271+
* @param key the key whose associated value is to be returned
272+
* @param offset the offset of the key
273+
* @param nodePosition the node to start a traverse
274+
* @return the value to which the specified key is mapped,
275+
* the offset of the key, and the node after the traverse
276+
*/
277+
public TraverseResult traverse(byte[] key, int offset, int nodePosition) {
278+
int nodePos = nodePosition;
279+
int id = nodePos;
280+
int unit = array.get(id);
281+
282+
for (int i = offset; i < key.length; i++) {
283+
byte k = key[i];
284+
id ^= offset(unit) ^ Byte.toUnsignedInt(k);
285+
unit = array.get(id);
286+
if (label(unit) != Byte.toUnsignedInt(k)) {
287+
return new TraverseResult(-2, i, nodePos);
288+
}
289+
nodePos = id;
290+
}
291+
if (!hasLeaf(unit)) {
292+
return new TraverseResult(-1, key.length, nodePos);
293+
}
294+
unit = array.get(nodePos ^ offset(unit));
295+
return new TraverseResult(value(unit), key.length, nodePos);
296+
}
297+
238298
private class Itr implements Iterator<int[]> {
239299
private final byte[] key;
240300
private int offset;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2019 Works Applications Co., Ltd.
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 com.worksap.nlp.dartsclone;
18+
19+
import java.nio.charset.StandardCharsets;
20+
21+
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertFalse;
23+
import static org.junit.Assert.assertNotEquals;
24+
import static org.junit.Assert.assertTrue;
25+
26+
import org.junit.Before;
27+
import org.junit.Rule;
28+
import org.junit.Test;
29+
import org.junit.rules.TemporaryFolder;
30+
31+
public class TraverseTest {
32+
33+
DoubleArray dic;
34+
35+
static final byte[] A = "a".getBytes(StandardCharsets.UTF_8);
36+
static final byte[] AB = "ab".getBytes(StandardCharsets.UTF_8);
37+
static final byte[] AC = "ac".getBytes(StandardCharsets.UTF_8);
38+
static final byte[] B = "b".getBytes(StandardCharsets.UTF_8);
39+
static final byte[] C = "c".getBytes(StandardCharsets.UTF_8);
40+
static final byte[] CD = "cd".getBytes(StandardCharsets.UTF_8);
41+
42+
@Before
43+
public void setUp() {
44+
byte[][] keys = new byte[][] { A, AB, CD };
45+
dic = new DoubleArray();
46+
dic.build(keys, null, null);
47+
}
48+
49+
@Test
50+
public void traverse() {
51+
DoubleArray.TraverseResult r = dic.traverse(A, 0, 0);
52+
assertTrue(r.result >= 0);
53+
assertEquals(1, r.offset);
54+
DoubleArray.TraverseResult r2 = dic.traverse(B, 0, r.nodePosition);
55+
assertTrue(r2.result >= 0);
56+
assertEquals(1, r2.offset);
57+
DoubleArray.TraverseResult r3 = dic.traverse(AB, 1, r.nodePosition);
58+
assertTrue(r3.result >= 0);
59+
assertEquals(2, r3.offset);
60+
}
61+
62+
@Test
63+
public void traverseNotMatchWithEnd() {
64+
DoubleArray.TraverseResult r = dic.traverse(C, 0, 0);
65+
assertEquals(-1, r.result);
66+
assertEquals(1, r.offset);
67+
DoubleArray.TraverseResult r2 = dic.traverse(CD, 1, r.nodePosition);
68+
assertTrue(r2.result >= 0);
69+
assertEquals(2, r2.offset);
70+
}
71+
72+
@Test
73+
public void traverseNotMatchMiddle() {
74+
DoubleArray.TraverseResult r = dic.traverse(AC, 0, 0);
75+
assertEquals(-2, r.result);
76+
assertEquals(1, r.offset);
77+
DoubleArray.TraverseResult r2 = dic.traverse(B, 0, r.nodePosition);
78+
assertTrue(r2.result >= 0);
79+
assertEquals(1, r2.offset);
80+
}
81+
}

0 commit comments

Comments
 (0)