@Override public FieldNameMatcher constructCIFieldNameMatcher(List<Named> matches, boolean alreadyInterned) { return BinaryNameMatcher.constructCaseInsensitive(matches, alreadyInterned); } }
@Override public FieldNameMatcher constructFieldNameMatcher(List<Named> matches, boolean alreadyInterned) { return BinaryNameMatcher.constructFrom(matches, alreadyInterned); }
private static BinaryNameMatcher _construct(List<String> symbols, SimpleNameMatcher base) { int sz = _findSize(symbols.size()); String[] lookup = symbols.toArray(new String[symbols.size()]); BinaryNameMatcher matcher = new BinaryNameMatcher(base, lookup, sz); for (String name : symbols) { matcher.addName(name); } return matcher; }
private int addName(String name, int q1, int q2, int q3) { final int index = _count; int offset = _findOffsetForAdd(calcHash(q1, q2, q3)); _hashArea[offset] = q1; _hashArea[offset+1] = q2; _hashArea[offset+2] = q3; _hashArea[offset+3] = _lengthAndIndex(3); // increases _count return index; }
public int addName(String name) { byte[] ch = name.getBytes(StandardCharsets.UTF_8); int len = ch.length; if (len <= 12) { if (len <= 4) { return addName(name, _decodeLast(ch, 0, len)); } int q1 = _decodeFull(ch, 0); if (len <= 8) { return addName(name, q1, _decodeLast(ch, 4, len-4)); } return addName(name, q1, _decodeFull(ch, 4), _decodeLast(ch, 8, len-8)); } int[] quads = _quads(name); return addName(name, quads, quads.length); }
private int addName(String name, int[] q, int qlen) { switch (qlen) { case 1: return addName(name, q[0]); case 2: return addName(name, q[0], q[1]); case 3: return addName(name, q[0], q[1], q[2]); } final int index = _count; final int hash = calcHash(q, qlen); int offset = _findOffsetForAdd(hash); _hashArea[offset] = hash; int longStart = _appendLongName(q, qlen); _hashArea[offset+1] = longStart; _hashArea[offset+3] = _lengthAndIndex(qlen); // increases _count return index; }
switch (qlen) { case 3: return matchByQuad(q[0], q[1], q[2]); case 2: return matchByQuad(q[0], q[1]); case 1: return matchByQuad(q[0]); default: // if 0 ever passed return -1; final int hash = calcHash(q, qlen); int offset = _calcOffset(hash); if (_verifyLongName(q, qlen, hashArea[offset+1])) { return lenAndIndex >> 16; if (_verifyLongName(q, qlen, hashArea[offset2+1])) { return lenAndIndex2 >> 16; return _findTertiary(offset, hash, q, qlen);
@Override public int matchByQuad(int q1, int q2) { int offset = _calcOffset(calcHash(q1, q2)); final int[] hashArea = _hashArea; int lenAndIndex = hashArea[offset+3]; if ((lenAndIndex & 0xFFFF) == 2) { if ((q1 == hashArea[offset]) && (q2 == hashArea[offset+1])) { return lenAndIndex >> 16; } } else if (lenAndIndex == 0) { // empty slot; unlikely but avoid further lookups if so return -1; } // secondary? int offset2 = _secondaryStart + ((offset >> 3) << 2); int lenAndIndex2 = hashArea[offset2+3]; if ((lenAndIndex2 & 0xFFFF) == 2) { if ((q1 == hashArea[offset2]) && (q2 == hashArea[offset2+1])) { return lenAndIndex2 >> 16; } } else if (lenAndIndex2 == 0) { // empty slot? Short-circuit if no more spillovers return -1; } return _findTertiary(offset, q1, q2); }
public static int[] _quads(String name) { final byte[] b = name.getBytes(StandardCharsets.UTF_8); final int len = b.length; int[] buf = new int[(len + 3) >> 2]; int in = 0; int out = 0; int left = len; for (; left > 4; left -= 4) { buf[out++] = _decodeFull(b, in); in += 4; } buf[out++] = _decodeLast(b, in, left); return buf; }
public static BinaryNameMatcher construct(List<String> symbols) { // Two-step process: since we need backup string-based lookup (when matching // current name, buffered etc etc), start with that return _construct(symbols, SimpleNameMatcher.construct(symbols)); }
/** * Constructor used for creating per-<code>JsonFactory</code> "root" * symbol tables: ones used for merging and sharing common symbols * * @param entryCount Number of Strings to contain * @param sz Size of logical hash area */ private BinaryNameMatcher(SimpleNameMatcher matcher, String[] nameLookup, int hashSize) { super(matcher, nameLookup); _count = 0; _hashSize = hashSize; // 8x, 4 ints per entry for main area, then sec/ter and spill over _hashArea = new int[hashSize << 3]; _secondaryStart = hashSize << 2; // right after primary area (at 50%) _tertiaryStart = _secondaryStart + (_secondaryStart >> 1); // right after secondary _tertiaryShift = _calcTertiaryShift(hashSize); _spilloverEnd = _hashArea.length - hashSize; // start AND end the same, at 7/8, initially _longNameOffset = _hashArea.length; // and start of long name area is at end of initial area (to be expanded) }
int offset = _calcOffset(hash); final int[] hashArea = _hashArea; if (hashArea[offset+3] == 0) {
private int addName(String name, int q1) { final int index = _count; int offset = _findOffsetForAdd(calcHash(q1)); _hashArea[offset] = q1; _hashArea[offset+3] = _lengthAndIndex(1); // increases _count return index; }
@Override public int matchByQuad(int q1, int q2, int q3) { int offset = _calcOffset(calcHash(q1, q2, q3)); final int[] hashArea = _hashArea; final int lenAndIndex = hashArea[offset+3]; if ((lenAndIndex & 0xFFFF) == 3) { if ((q1 == hashArea[offset]) && (hashArea[offset+1] == q2) && (hashArea[offset+2] == q3)) { return lenAndIndex >> 16; } } else if (lenAndIndex == 0) { // empty slot; unlikely but avoid further lookups if so return -1; } // secondary? int offset2 = _secondaryStart + ((offset >> 3) << 2); final int lenAndIndex2 = hashArea[offset2+3]; if ((lenAndIndex2 & 0xFFFF) == 3) { if ((q1 == hashArea[offset2]) && (hashArea[offset2+1] == q2) && (hashArea[offset2+2] == q3)) { return lenAndIndex2 >> 16; } } else if (lenAndIndex2 == 0) { // empty slot? Short-circuit if no more spillovers return -1; } return _findTertiary(offset, q1, q2, q3); }
public static BinaryNameMatcher constructCaseInsensitive(List<Named> fields, boolean alreadyInterned) { final List<String> names = FieldNameMatcher.stringsFromNames(fields, alreadyInterned); return _construct(names, SimpleNameMatcher.constructCaseInsensitive(names)); }
private int addName(String name, int q1, int q2) { final int index = _count; int offset = _findOffsetForAdd(calcHash(q1, q2)); _hashArea[offset] = q1; _hashArea[offset+1] = q2; _hashArea[offset+3] = _lengthAndIndex(2); // increases _count return index; }
@Override public int matchByQuad(int q1) { int offset = _calcOffset(calcHash(q1)); // first: primary match? final int[] hashArea = _hashArea; int lenAndIndex = hashArea[offset+3]; if ((lenAndIndex & 0xFFFF) == 1) { if (hashArea[offset] == q1) { return lenAndIndex >> 16; } } else if (lenAndIndex == 0) { // empty slot; unlikely but avoid further lookups if so return -1; } // secondary? single slot shared by N/2 primaries int offset2 = _secondaryStart + ((offset >> 3) << 2); lenAndIndex = hashArea[offset2+3]; if ((lenAndIndex & 0xFFFF) == 1) { if (hashArea[offset2] == q1) { return lenAndIndex >> 16; } } else if (lenAndIndex == 0) { // empty slot; unlikely but avoid further lookups if so return -1; } // tertiary lookup & spillovers best to offline return _findTertiary(offset, q1); }
@Override public FieldNameMatcher constructCIFieldNameMatcher(List<Named> matches, boolean alreadyInterned) { return BinaryNameMatcher.constructCaseInsensitive(matches, alreadyInterned); } }
@Override public FieldNameMatcher constructFieldNameMatcher(List<Named> matches, boolean alreadyInterned) { return BinaryNameMatcher.constructFrom(matches, alreadyInterned); }