This repository was archived by the owner on May 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathStringKeyAnalyzer.java
More file actions
executable file
·131 lines (105 loc) · 3.09 KB
/
StringKeyAnalyzer.java
File metadata and controls
executable file
·131 lines (105 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright 2010 Roger Kapsi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ardverk.collection;
import java.io.Serializable;
/**
* A {@link KeyAnalyzer} for {@link String}s.
*/
public class StringKeyAnalyzer extends AbstractKeyAnalyzer<String>
implements Serializable {
private static final long serialVersionUID = 7677641007465182788L;
/**
* A {@link StringKeyAnalyzer} that uses all bits (16) of a {@code char}.
*/
public static final StringKeyAnalyzer CHAR = new StringKeyAnalyzer(Character.SIZE);
/**
* A {@link StringKeyAnalyzer} that uses only the lower 8 bits of each {@code char}.
*/
public static final StringKeyAnalyzer BYTE = new StringKeyAnalyzer(Byte.SIZE);
@Deprecated
public static final StringKeyAnalyzer INSTANCE = CHAR;
private final int size;
private final int msb;
private StringKeyAnalyzer(int size) {
this(size, 1 << size-1);
}
private StringKeyAnalyzer(int size, int msb) {
this.size = size;
this.msb = msb;
}
/**
* Returns a bit mask where the given bit is set
*/
private int mask(int bit) {
return msb >>> bit;
}
/**
* Returns the {@code char} at the given index.
*/
private char valueAt(String value, int index) {
if (index < value.length()) {
char ch = value.charAt(index);
if (size == Byte.SIZE) {
ch &= 0xFF;
}
return ch;
}
return 0;
}
@Override
public int lengthInBits(String key) {
return key.length() * size;
}
@Override
public boolean isBitSet(String key, int bitIndex) {
if (bitIndex >= lengthInBits(key)) {
return false;
}
int index = (int)(bitIndex / size);
int bit = (int)(bitIndex % size);
return (key.charAt(index) & mask(bit)) != 0;
}
@Override
public boolean isPrefix(String key, String prefix) {
return key.startsWith(prefix);
}
@Override
public int bitIndex(String key, String otherKey) {
boolean allNull = true;
int length = Math.max(key.length(), otherKey.length());
for (int i = 0; i < length; i++) {
char ch1 = valueAt(key, i);
char ch2 = valueAt(otherKey, i);
if (ch1 != ch2) {
int xor = ch1 ^ ch2;
for (int j = 0; j < size; j++) {
if ((xor & mask(j)) != 0) {
return (i * size) + j;
}
}
}
if (ch1 != 0) {
allNull = false;
}
}
// All bits are 0
if (allNull) {
return KeyAnalyzer.NULL_BIT_KEY;
}
// Both keys are equal
return KeyAnalyzer.EQUAL_BIT_KEY;
}
}