|
5 | 5 | import com.github.benmanes.caffeine.cache.stats.CacheStats; |
6 | 6 |
|
7 | 7 | /** |
8 | | - * "Fast" string which uses a combination of cacheing and fingerprinting |
| 8 | + * "Fast" string which uses "fingerprinting" |
9 | 9 | * to make both equality comparison, and string ordering efficient for |
10 | 10 | * shorter/simpler strings. |
11 | 11 | * <p> |
12 | | - * The first tactic is to cache {@code String} to {@code Str} mappings for |
13 | | - * most recently used {@code String}s of {@code Str}s. |
14 | | - * This allows equality comparisons to often succeed based on identity. |
15 | | - * <p> |
16 | | - * The second tactic is to create a fingerprint (a {@code long}, i.e. 64 bits) for a string. |
| 12 | + * The tactic is to create a fingerprint (a {@code long}, i.e. 64 bits) for a string. |
17 | 13 | * The fingerprint holds |
18 | 14 | * - a prefix (the first 8 bits of the first 6 characters) |
19 | 15 | * - a length (0...254, or 255 representing length >= 255). |
@@ -80,7 +76,7 @@ private static Str from(final String s) { |
80 | 76 | * @return true iff the string is empty |
81 | 77 | */ |
82 | 78 | public boolean isEmpty() { |
83 | | - return value.isEmpty(); |
| 79 | + return ((fingerprint & LENGTH_MASK) == 0L); |
84 | 80 | } |
85 | 81 |
|
86 | 82 | public CharSequence toCharSequence() { |
@@ -137,18 +133,21 @@ private boolean lexicographicPrefix() { |
137 | 133 | * @return the length of the string which this @{Str represents} |
138 | 134 | */ |
139 | 135 | public int length() { |
140 | | - long lsb = (fingerprint >> LEN_SHIFT) & 0xff; |
| 136 | + long lsb = (fingerprint >>> LEN_SHIFT) & 0xff; |
141 | 137 | if (lsb < 0xff) { |
142 | 138 | return (int) lsb; |
143 | 139 | } |
144 | 140 | return value.length(); |
145 | 141 | } |
146 | 142 |
|
| 143 | + // Configuration for masking |
147 | 144 | private final static int LEN_SHIFT = 48; |
148 | 145 | private final static int MAX_FINGERPRINT_ENCODED_LEN = 6; |
149 | 146 |
|
150 | 147 | private final static long PREFIX_MASK = 0xffffffffffffL; |
151 | 148 |
|
| 149 | + private final static long LENGTH_MASK = 0xffL << LEN_SHIFT; |
| 150 | + |
152 | 151 | /** |
153 | 152 | * Create a fingerprint for a string, to make comparison more efficient |
154 | 153 | * <p> |
@@ -210,7 +209,18 @@ public boolean equals(Object o) { |
210 | 209 | */ |
211 | 210 | @Override |
212 | 211 | public int hashCode() { |
213 | | - return (int) (fingerprint ^ (fingerprint >>> 32)); |
| 212 | + // fingerprint bytes |
| 213 | + // 7 or of top 8 bits of each char |
| 214 | + // 6 length up to 255 |
| 215 | + // 5 char 0 (bottom 8 bits) |
| 216 | + // 4 char 1 |
| 217 | + // 3 char 2 |
| 218 | + // 2 char 3 |
| 219 | + // 1 char 4 |
| 220 | + // 0 char 5 |
| 221 | + // >>> 40 gets char 0 into the least bit of the hash, length above it |
| 222 | + // >>> 20 gets char 1 into the middle of the hash |
| 223 | + return (int) (fingerprint ^ (fingerprint >>> 40) ^ (fingerprint >>> 20)); |
214 | 224 | } |
215 | 225 |
|
216 | 226 |
|
|
0 commit comments