|
17 | 17 | package com.netflix.hollow.tools.history.keyindex;
|
18 | 18 |
|
19 | 19 | import static com.netflix.hollow.core.HollowConstants.ORDINAL_NONE;
|
| 20 | +import static com.netflix.hollow.tools.util.SearchUtils.ESCAPED_MULTI_FIELD_KEY_DELIMITER; |
20 | 21 | import static com.netflix.hollow.tools.util.SearchUtils.MULTI_FIELD_KEY_DELIMITER;
|
21 | 22 |
|
22 | 23 | import com.netflix.hollow.core.HollowDataset;
|
|
31 | 32 | import com.netflix.hollow.core.util.RemovedOrdinalIterator;
|
32 | 33 | import java.util.Arrays;
|
33 | 34 | import java.util.BitSet;
|
| 35 | +import java.util.Objects; |
| 36 | +import java.util.Set; |
34 | 37 |
|
35 | 38 | public class HollowHistoryTypeKeyIndex {
|
36 | 39 | private final PrimaryKey primaryKey;
|
@@ -175,50 +178,92 @@ public String getKeyDisplayString(int keyOrdinal) {
|
175 | 178 | return builder.toString();
|
176 | 179 | }
|
177 | 180 |
|
178 |
| - public IntList queryIndexedFields(final String query) { |
179 |
| - IntList matchingKeys = new IntList(); |
| 181 | + private void getMatchesForField(int fieldIdx, String strVal, IntList matchingKeys) throws NumberFormatException { |
| 182 | + int hashCode = 0; |
| 183 | + Object objectToFind = null; |
| 184 | + FieldType fieldType = fieldTypes[fieldIdx]; |
| 185 | + switch (fieldType) { |
| 186 | + case INT: |
| 187 | + final int queryInt = Integer.parseInt(strVal); |
| 188 | + hashCode = HollowReadFieldUtils.intHashCode(queryInt); |
| 189 | + objectToFind = queryInt; |
| 190 | + break; |
| 191 | + case LONG: |
| 192 | + final long queryLong = Long.parseLong(strVal); |
| 193 | + hashCode = HollowReadFieldUtils.longHashCode(queryLong); |
| 194 | + objectToFind = queryLong; |
| 195 | + break; |
| 196 | + case STRING: |
| 197 | + hashCode = HashCodes.hashCode(strVal); |
| 198 | + objectToFind = strVal.replaceAll(ESCAPED_MULTI_FIELD_KEY_DELIMITER, MULTI_FIELD_KEY_DELIMITER); |
| 199 | + break; |
| 200 | + case DOUBLE: |
| 201 | + final double queryDouble = Double.parseDouble(strVal); |
| 202 | + hashCode = HollowReadFieldUtils.doubleHashCode(queryDouble); |
| 203 | + objectToFind = queryDouble; |
| 204 | + break; |
| 205 | + case FLOAT: |
| 206 | + final float queryFloat = Float.parseFloat(strVal); |
| 207 | + hashCode = HollowReadFieldUtils.floatHashCode(queryFloat); |
| 208 | + objectToFind = queryFloat; |
| 209 | + break; |
| 210 | + default: |
| 211 | + } |
| 212 | + ordinalMapping.addMatches(HashCodes.hashInt(hashCode), objectToFind, fieldIdx, fieldType, matchingKeys); |
| 213 | + } |
180 | 214 |
|
181 |
| - if (!isInitialized) { |
182 |
| - return matchingKeys; |
| 215 | + // find the exact matches for the given composite key. |
| 216 | + private IntList queryIndexedFieldsForCompositeKey(final String[] compositeKeyComponents) { |
| 217 | + IntList matchingKeys = new IntList(); |
| 218 | + Set<Integer> resultSet = null; |
| 219 | + for (int i = 0; i < compositeKeyComponents.length; ++i) { |
| 220 | + String currComponent = compositeKeyComponents[i]; |
| 221 | + try { |
| 222 | + getMatchesForField(i, currComponent, matchingKeys); |
| 223 | + Set<Integer> keySet = IntList.createSetFromIntList(matchingKeys); |
| 224 | + matchingKeys.clear(); |
| 225 | + if (keySet.isEmpty()) { |
| 226 | + // directly return as we'll not be able to find any exact matches for the given |
| 227 | + // composite key. |
| 228 | + return new IntList(); |
| 229 | + } |
| 230 | + if (Objects.isNull(resultSet)) { |
| 231 | + resultSet = keySet; |
| 232 | + } |
| 233 | + else { |
| 234 | + resultSet.retainAll(keySet); |
| 235 | + } |
| 236 | + } catch (NumberFormatException ignore) { |
| 237 | + return new IntList(); |
| 238 | + } |
183 | 239 | }
|
184 | 240 |
|
| 241 | + return IntList.createIntListFromSet(resultSet); |
| 242 | + } |
| 243 | + |
| 244 | + private IntList queryIndexedFieldsForNonCompositeKey(final String query) { |
| 245 | + IntList matchingKeys = new IntList(); |
185 | 246 | for (int i = 0; i < primaryKey.numFields(); i++) {
|
186 |
| - int hashCode = 0; |
187 |
| - Object objectToFind = null; |
188 | 247 | try {
|
189 |
| - switch (fieldTypes[i]) { |
190 |
| - case INT: |
191 |
| - final int queryInt = Integer.parseInt(query); |
192 |
| - hashCode = HollowReadFieldUtils.intHashCode(queryInt); |
193 |
| - objectToFind = queryInt; |
194 |
| - break; |
195 |
| - case LONG: |
196 |
| - final long queryLong = Long.parseLong(query); |
197 |
| - hashCode = HollowReadFieldUtils.longHashCode(queryLong); |
198 |
| - objectToFind = queryLong; |
199 |
| - break; |
200 |
| - case STRING: |
201 |
| - hashCode = HashCodes.hashCode(query); |
202 |
| - objectToFind = query; |
203 |
| - break; |
204 |
| - case DOUBLE: |
205 |
| - final double queryDouble = Double.parseDouble(query); |
206 |
| - hashCode = HollowReadFieldUtils.doubleHashCode(queryDouble); |
207 |
| - objectToFind = queryDouble; |
208 |
| - break; |
209 |
| - case FLOAT: |
210 |
| - final float queryFloat = Float.parseFloat(query); |
211 |
| - hashCode = HollowReadFieldUtils.floatHashCode(queryFloat); |
212 |
| - objectToFind = queryFloat; |
213 |
| - break; |
214 |
| - default: |
215 |
| - } |
216 |
| - ordinalMapping.addMatches(HashCodes.hashInt(hashCode), objectToFind, i, fieldTypes[i], matchingKeys); |
| 248 | + getMatchesForField(i, query, matchingKeys); |
217 | 249 | } catch(NumberFormatException ignore) {}
|
218 | 250 | }
|
219 | 251 | return matchingKeys;
|
220 | 252 | }
|
221 | 253 |
|
| 254 | + public IntList queryIndexedFields(final String query) { |
| 255 | + if (!isInitialized) { |
| 256 | + return new IntList(); |
| 257 | + } |
| 258 | + |
| 259 | + String[] keyComponents = query.split("(?<!\\\\)" + MULTI_FIELD_KEY_DELIMITER, primaryKey.numFields()); |
| 260 | + if (keyComponents.length > 1 && keyComponents.length == primaryKey.numFields()) { |
| 261 | + return queryIndexedFieldsForCompositeKey(keyComponents); |
| 262 | + } else { |
| 263 | + return queryIndexedFieldsForNonCompositeKey(query); |
| 264 | + } |
| 265 | + } |
| 266 | + |
222 | 267 | public Object getKeyFieldValue(int keyFieldIdx, int keyOrdinal) {
|
223 | 268 | return ordinalMapping.getFieldObject(keyOrdinal, keyFieldIdx, fieldTypes[keyFieldIdx]);
|
224 | 269 | }
|
|
0 commit comments