Top Description Inners Fields Constructors Methods
com.fasterxml.jackson.core.sym

public final Class ByteQuadsCanonicalizer

extends Object
Class Inheritance
Imports
java.util.Arrays, java.util.concurrent.atomic.AtomicReference, com.fasterxml.jackson.core.JsonFactory, com.fasterxml.jackson.core.exc.StreamConstraintsException, com.fasterxml.jackson.core.util.InternCache

Replacement for BytesToNameCanonicalizer which aims at more localized memory access due to flattening of name quad data. Performance improvement modest for simple JSON document data binding (maybe 3%), but should help more for larger symbol tables, or for binary formats like Smile.

Hash area is divided into 4 sections:

  1. Primary area (1/2 of total size), direct match from hash (LSB)
  2. Secondary area (1/4 of total size), match from hash (LSB) >> 1
  3. Tertiary area (1/8 of total size), match from hash (LSB) >> 2
  4. Spill-over area (remaining 1/8) with linear scan, insertion order
and within every area, entries are 4 ints, where 1 - 3 ints contain 1 - 12 UTF-8 encoded bytes of name (null-padded), and last int is offset in _names that contains actual name Strings.
Since
2.6

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
ByteQuadsCanonicalizer.TableInfo

Immutable value class used for sharing information as efficiently as possible, by only require synchronization of reference manipulation but not access to contents.

Field Summary

Modifier and TypeField and Description
protected int
_count

Total number of Strings in the symbol table; only used for child tables.

protected final boolean
_failOnDoS

Flag that indicates whether we should throw an exception if enough hash collisions are detected (true); or just worked around (false).

protected int[]
_hashArea

Primary hash information area: consists of 2 * _hashSize entries of 16 bytes (4 ints), arranged in a cascading lookup structure (details of which may be tweaked depending on expected rates of collisions).

protected boolean
_hashShared

Flag that indicates whether underlying data structures for the main hash area are shared or not.

protected int
_hashSize

Number of slots for primary entries within _hashArea; which is at most 1/8 of actual size of the underlying array (4-int slots, primary covers only half of the area; plus, additional area for longer symbols after hash area).

protected final InternCache
_interner

Entity that knows how to intern Strings, if needed, or null if no interning is wanted.

protected int
_longNameOffset

Offset within _hashArea that follows main slots and contains quads for longer names (13 bytes or longer), and points to the first available int that may be used for appending quads of the next long name.

protected String[]
_names

Array that contains String instances matching entries in _hashArea.

protected final ByteQuadsCanonicalizer
_parent

Reference to the root symbol table, for child tables, so that they can merge table information back as necessary.

protected int
_secondaryStart

Offset within _hashArea where secondary entries start

protected final int
_seed

Seed value we use as the base to make hash codes non-static between different runs, but still stable for lifetime of a single symbol table instance.

protected int
_spilloverEnd

Pointer to the offset within spill-over area where there is room for more spilled over entries (if any).

protected final AtomicReference<ByteQuadsCanonicalizer.TableInfo>
_tableInfo

Member that is only used by the root table instance: root passes immutable state info child instances, and children may return new state if they add entries to the table.

protected int
_tertiaryShift

Constant that determines size of buckets for tertiary entries: 1 << _tertiaryShift is the size, and shift value is also used for translating from primary offset into tertiary bucket (shift right by 4 + _tertiaryShift).

protected int
_tertiaryStart

Offset within _hashArea where tertiary entries start

private static final int
DEFAULT_T_SIZE

Initial size of the primary hash area.

protected static final int
MAX_ENTRIES_FOR_REUSE

Let's only share reasonably sized symbol tables.

private static final int
MAX_T_SIZE

Let's not expand symbol tables past some maximum size; with unique (~= random) names.

private static final int
MIN_HASH_SIZE

No point in trying to construct tiny tables, just need to resize soon.

private static final int
private static final int
private static final int

Constructor Summary

AccessConstructor and Description
private
ByteQuadsCanonicalizer(int
Initial primary hash area size
sz
,
int
Random seed valued used to make it more difficult to cause collisions (used for collision-based DoS attacks).
seed
)

Constructor used for creating per-TokenStreamFactory "root" symbol tables: ones used for merging and sharing common symbols

private
ByteQuadsCanonicalizer(ByteQuadsCanonicalizer parent, int seed, ByteQuadsCanonicalizer.TableInfo state, boolean intern, boolean failOnDoS)

Constructor used when creating a child instance

private
ByteQuadsCanonicalizer(ByteQuadsCanonicalizer.TableInfo state)

Alternate constructor used in cases where a "placeholder" child instance is needed when symbol table is not really used, but caller needs a non-null placeholder to keep code functioning with minimal awareness of distinction (all lookups fail to match any name without error; add methods should NOT be called).

Method Summary

Modifier and TypeMethod and Description
private int
_appendLongName(int[] quads, int qlen)

private final int
_calcOffset(int hash)

pack-priv static int
_calcTertiaryShift(int primarySlots)

private boolean
private int
_findOffsetForAdd(int
Hash of name for which to find location
hash
)

Method called to find the location within hash table to add a new symbol in.

private String
_findSecondary(int origOffset, int q1)

private String
_findSecondary(int origOffset, int q1, int q2)

private String
_findSecondary(int origOffset, int q1, int q2, int q3)

private String
_findSecondary(int origOffset, int hash, int[] q, int qlen)

protected void
private int
private final int
_spilloverStart()

Helper method that calculates start of the spillover area

private boolean
_verifyLongName(int[] q, int qlen, int spillOffset)

private boolean
_verifyLongName2(int[] q, int qlen, int spillOffset)

private void
public String

Returns:

name (possibly interned)
addName
(String
Name to add
name
,
int
Quad representation of the name
q1
)

public String

Returns:

name (possibly interned)
addName
(String
Name to add
name
,
int
First quad of name representation
q1
,
int
Second quad of name representation
q2
)

public String

Returns:

name (possibly interned)
addName
(String
Name to add
name
,
int
First quad of name representation
q1
,
int
Second quad of name representation
q2
,
int
Third quad of name representation
q3
)

public String

Returns:

name (possibly interned)
addName
(String
Name to add
name
,
int[]
Quads of name representation
q
,
int
Number of quads in q
qlen
)

public int

Returns:

number of primary slots table has currently
bucketCount
()

public int
calcHash(int q1)

public int
calcHash(int q1, int q2)

public int
calcHash(int q1, int q2, int q3)

public int

Returns:

hash
calcHash
(int[]
int array
q
,
int
length
qlen
)

public static ByteQuadsCanonicalizer

Returns:

Root instance to use for constructing new child instances
createRoot
()

Factory method to call to create a symbol table instance with a randomized seed value.

protected static ByteQuadsCanonicalizer
createRoot(int seed)

public String
findName(int q1)

public String
findName(int q1, int q2)

public String
findName(int q1, int q2, int q3)

public String
findName(int[] q, int qlen)

public int
public boolean

Returns:

True for "real", canonicalizing child tables; false for root table as well as placeholder "child" tables.
isCanonicalizing
()

public ByteQuadsCanonicalizer

Returns:

Actual canonicalizer instance that can be used by a parser
makeChild
(int flags)

Factory method used to create actual symbol table instance to use for parsing.

public ByteQuadsCanonicalizer

Returns:

Actual canonicalizer instance that can be used by a parser if (and only if) canonicalization is enabled; otherwise a non-null "placeholder" instance.
makeChildOrPlaceholder
(int flags)

Method similar to makeChild but one that only creates real instance of com.fasterxml.jackson.core.JsonFactory.Feature#CANONICALIZE_FIELD_NAMES is enabled: otherwise a "bogus" instance is created.

public boolean

Returns:

Whether main hash area has been modified
maybeDirty
()

Method called to check to quickly see if a child symbol table may have gotten additional entries.

private void
pack-priv static int
private void
nukeSymbols(boolean fill)

Helper method called to empty all shared symbols, but to leave arrays allocated

public int

Returns:

Number of entries in the primary hash area
primaryCount
()

Method mostly needed by unit tests; calculates number of entries that are in the primary slot set.

private void
public void
release()

Method called by the using code to indicate it is done with this instance.

public int

Returns:

Number of entries in the secondary hash area
secondaryCount
()

Method mostly needed by unit tests; calculates number of entries in secondary buckets

public int

Returns:

Number of symbol entries contained by this canonicalizer instance
size
()

public int

Returns:

Number of entries in the linear spill-over areay
spilloverCount
()

Method mostly needed by unit tests; calculates number of entries in shared spill-over area

public int

Returns:

Number of entries in the tertiary hash area
tertiaryCount
()

Method mostly needed by unit tests; calculates number of entries in tertiary buckets

public String
toString()

Overrides java.lang.Object.toString.

Returns a string representation of the object.

public int
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAllwaitwaitwait

Field Detail

_countback to summary
protected int _count

Total number of Strings in the symbol table; only used for child tables.

_failOnDoSback to summary
protected final boolean _failOnDoS

Flag that indicates whether we should throw an exception if enough hash collisions are detected (true); or just worked around (false).

Since
2.4
_hashAreaback to summary
protected int[] _hashArea

Primary hash information area: consists of 2 * _hashSize entries of 16 bytes (4 ints), arranged in a cascading lookup structure (details of which may be tweaked depending on expected rates of collisions).

_hashSharedback to summary
protected boolean _hashShared

Flag that indicates whether underlying data structures for the main hash area are shared or not. If they are, then they need to be handled in copy-on-write way, i.e. if they need to be modified, a copy needs to be made first; at this point it will not be shared any more, and can be modified.

This flag needs to be checked both when adding new main entries, and when adding new collision list queues (i.e. creating a new collision list head entry)

_hashSizeback to summary
protected int _hashSize

Number of slots for primary entries within _hashArea; which is at most 1/8 of actual size of the underlying array (4-int slots, primary covers only half of the area; plus, additional area for longer symbols after hash area).

_internerback to summary
protected final InternCache _interner

Entity that knows how to intern Strings, if needed, or null if no interning is wanted.

Since
2.16
_longNameOffsetback to summary
protected int _longNameOffset

Offset within _hashArea that follows main slots and contains quads for longer names (13 bytes or longer), and points to the first available int that may be used for appending quads of the next long name. Note that long name area follows immediately after the fixed-size main hash area (_hashArea).

_namesback to summary
protected String[] _names

Array that contains String instances matching entries in _hashArea. Contains nulls for unused entries. Note that this size is twice that of _hashArea

_parentback to summary
protected final ByteQuadsCanonicalizer _parent

Reference to the root symbol table, for child tables, so that they can merge table information back as necessary.

_secondaryStartback to summary
protected int _secondaryStart

Offset within _hashArea where secondary entries start

_seedback to summary
protected final int _seed

Seed value we use as the base to make hash codes non-static between different runs, but still stable for lifetime of a single symbol table instance. This is done for security reasons, to avoid potential DoS attack via hash collisions.

_spilloverEndback to summary
protected int _spilloverEnd

Pointer to the offset within spill-over area where there is room for more spilled over entries (if any). Spill over area is within fixed-size portion of _hashArea.

_tableInfoback to summary
protected final AtomicReference<ByteQuadsCanonicalizer.TableInfo> _tableInfo

Member that is only used by the root table instance: root passes immutable state info child instances, and children may return new state if they add entries to the table. Child tables do NOT use the reference.

_tertiaryShiftback to summary
protected int _tertiaryShift

Constant that determines size of buckets for tertiary entries: 1 << _tertiaryShift is the size, and shift value is also used for translating from primary offset into tertiary bucket (shift right by 4 + _tertiaryShift).

Default value is 2, for buckets of 4 slots; grows bigger with bigger table sizes.

_tertiaryStartback to summary
protected int _tertiaryStart

Offset within _hashArea where tertiary entries start

DEFAULT_T_SIZEback to summary
private static final int DEFAULT_T_SIZE

Initial size of the primary hash area. Each entry consumes 4 ints (16 bytes), and secondary area is same as primary; so default size will use 2kB of memory (plus 64x4 or 64x8 (256/512 bytes) for references to Strings, and Strings themselves).

MAX_ENTRIES_FOR_REUSEback to summary
protected static final int MAX_ENTRIES_FOR_REUSE

Let's only share reasonably sized symbol tables. Max size set to 3/4 of 8k; this corresponds to 256k main hash index. This should allow for enough distinct names for almost any case, while preventing ballooning for cases where names are unique (or close thereof).

MAX_T_SIZEback to summary
private static final int MAX_T_SIZE

Let's not expand symbol tables past some maximum size; with unique (~= random) names. Size is in

MIN_HASH_SIZEback to summary
private static final int MIN_HASH_SIZE

No point in trying to construct tiny tables, just need to resize soon.

MULTback to summary
private static final int MULT
MULT2back to summary
private static final int MULT2
MULT3back to summary
private static final int MULT3

Constructor Detail

ByteQuadsCanonicalizerback to summary
private ByteQuadsCanonicalizer(int sz, int seed)

Constructor used for creating per-TokenStreamFactory "root" symbol tables: ones used for merging and sharing common symbols

Parameters
sz:int

Initial primary hash area size

seed:int

Random seed valued used to make it more difficult to cause collisions (used for collision-based DoS attacks).

ByteQuadsCanonicalizerback to summary
private ByteQuadsCanonicalizer(ByteQuadsCanonicalizer parent, int seed, ByteQuadsCanonicalizer.TableInfo state, boolean intern, boolean failOnDoS)

Constructor used when creating a child instance

ByteQuadsCanonicalizerback to summary
private ByteQuadsCanonicalizer(ByteQuadsCanonicalizer.TableInfo state)

Alternate constructor used in cases where a "placeholder" child instance is needed when symbol table is not really used, but caller needs a non-null placeholder to keep code functioning with minimal awareness of distinction (all lookups fail to match any name without error; add methods should NOT be called).

Since
2.13

Method Detail

_appendLongNameback to summary
private int _appendLongName(int[] quads, int qlen)
_calcOffsetback to summary
private final int _calcOffset(int hash)
_calcTertiaryShiftback to summary
pack-priv static int _calcTertiaryShift(int primarySlots)
_checkNeedForRehashback to summary
private boolean _checkNeedForRehash()
_findOffsetForAddback to summary
private int _findOffsetForAdd(int hash) throws StreamConstraintsException

Method called to find the location within hash table to add a new symbol in.

Parameters
hash:int

Hash of name for which to find location

Exceptions
StreamConstraintsException:
If name length exceeds maximum allowed.
_findSecondaryback to summary
private String _findSecondary(int origOffset, int q1)
_findSecondaryback to summary
private String _findSecondary(int origOffset, int q1, int q2)
_findSecondaryback to summary
private String _findSecondary(int origOffset, int q1, int q2, int q3)
_findSecondaryback to summary
private String _findSecondary(int origOffset, int hash, int[] q, int qlen)
_reportTooManyCollisionsback to summary
protected void _reportTooManyCollisions() throws StreamConstraintsException
_resizeAndFindOffsetForAddback to summary
private int _resizeAndFindOffsetForAdd(int hash) throws StreamConstraintsException
_spilloverStartback to summary
private final int _spilloverStart()

Helper method that calculates start of the spillover area

_verifyLongNameback to summary
private boolean _verifyLongName(int[] q, int qlen, int spillOffset)
_verifyLongName2back to summary
private boolean _verifyLongName2(int[] q, int qlen, int spillOffset)
_verifySharingback to summary
private void _verifySharing()
addNameback to summary
public String addName(String name, int q1) throws StreamConstraintsException
Parameters
name:String

Name to add

q1:int

Quad representation of the name

Returns:String

name (possibly interned)

Exceptions
StreamConstraintsException:
if the constraint exceptions
addNameback to summary
public String addName(String name, int q1, int q2) throws StreamConstraintsException
Parameters
name:String

Name to add

q1:int

First quad of name representation

q2:int

Second quad of name representation

Returns:String

name (possibly interned)

Exceptions
StreamConstraintsException:
if the constraint exceptions
addNameback to summary
public String addName(String name, int q1, int q2, int q3) throws StreamConstraintsException
Parameters
name:String

Name to add

q1:int

First quad of name representation

q2:int

Second quad of name representation

q3:int

Third quad of name representation

Returns:String

name (possibly interned)

Exceptions
StreamConstraintsException:
if the constraint exceptions
addNameback to summary
public String addName(String name, int[] q, int qlen) throws StreamConstraintsException
Parameters
name:String

Name to add

q:int[]

Quads of name representation

qlen:int

Number of quads in q

Returns:String

name (possibly interned)

Exceptions
StreamConstraintsException:
if the constraint exceptions
bucketCountback to summary
public int bucketCount()
Returns:int

number of primary slots table has currently

calcHashback to summary
public int calcHash(int q1)
calcHashback to summary
public int calcHash(int q1, int q2)
calcHashback to summary
public int calcHash(int q1, int q2, int q3)
calcHashback to summary
public int calcHash(int[] q, int qlen)
Parameters
q:int[]

int array

qlen:int

length

Returns:int

hash

Exceptions
IllegalArgumentException:
if qlen is less than 4
createRootback to summary
public static ByteQuadsCanonicalizer createRoot()

Factory method to call to create a symbol table instance with a randomized seed value.

Returns:ByteQuadsCanonicalizer

Root instance to use for constructing new child instances

createRootback to summary
protected static ByteQuadsCanonicalizer createRoot(int seed)
findNameback to summary
public String findName(int q1)
findNameback to summary
public String findName(int q1, int q2)
findNameback to summary
public String findName(int q1, int q2, int q3)
findNameback to summary
public String findName(int[] q, int qlen)
hashSeedback to summary
public int hashSeed()
isCanonicalizingback to summary
public boolean isCanonicalizing()
Returns:boolean

True for "real", canonicalizing child tables; false for root table as well as placeholder "child" tables.

Since
2.13
makeChildback to summary
public ByteQuadsCanonicalizer makeChild(int flags)

Factory method used to create actual symbol table instance to use for parsing.

Parameters
flags:int

Bit flags of active com.fasterxml.jackson.core.JsonFactory.Features enabled.

Returns:ByteQuadsCanonicalizer

Actual canonicalizer instance that can be used by a parser

makeChildOrPlaceholderback to summary
public ByteQuadsCanonicalizer makeChildOrPlaceholder(int flags)

Method similar to makeChild but one that only creates real instance of com.fasterxml.jackson.core.JsonFactory.Feature#CANONICALIZE_FIELD_NAMES is enabled: otherwise a "bogus" instance is created.

Parameters
flags:int

Bit flags of active com.fasterxml.jackson.core.JsonFactory.Features enabled.

Returns:ByteQuadsCanonicalizer

Actual canonicalizer instance that can be used by a parser if (and only if) canonicalization is enabled; otherwise a non-null "placeholder" instance.

Since
2.13
maybeDirtyback to summary
public boolean maybeDirty()

Method called to check to quickly see if a child symbol table may have gotten additional entries. Used for checking to see if a child table should be merged into shared table.

Returns:boolean

Whether main hash area has been modified

mergeChildback to summary
private void mergeChild(ByteQuadsCanonicalizer.TableInfo childState)
multiplyByFourFifthsback to summary
pack-priv static int multiplyByFourFifths(int number)
nukeSymbolsback to summary
private void nukeSymbols(boolean fill)

Helper method called to empty all shared symbols, but to leave arrays allocated

primaryCountback to summary
public int primaryCount()

Method mostly needed by unit tests; calculates number of entries that are in the primary slot set. These are "perfect" entries, accessible with a single lookup

Returns:int

Number of entries in the primary hash area

rehashback to summary
private void rehash() throws StreamConstraintsException
releaseback to summary
public void release()

Method called by the using code to indicate it is done with this instance. This lets instance merge accumulated changes into parent (if need be), safely and efficiently, and without calling code having to know about parent information.

secondaryCountback to summary
public int secondaryCount()

Method mostly needed by unit tests; calculates number of entries in secondary buckets

Returns:int

Number of entries in the secondary hash area

sizeback to summary
public int size()
Returns:int

Number of symbol entries contained by this canonicalizer instance

spilloverCountback to summary
public int spilloverCount()

Method mostly needed by unit tests; calculates number of entries in shared spill-over area

Returns:int

Number of entries in the linear spill-over areay

tertiaryCountback to summary
public int tertiaryCount()

Method mostly needed by unit tests; calculates number of entries in tertiary buckets

Returns:int

Number of entries in the tertiary hash area

toStringback to summary
public String toString()

Overrides java.lang.Object.toString.

Doc from java.lang.Object.toString.

Returns a string representation of the object. Satisfying this method's contract implies a non-null result must be returned.

Returns:String

a string representation of the object

Annotations
@Override
totalCountback to summary
public int totalCount()
com.fasterxml.jackson.core.sym back to summary

private final Class ByteQuadsCanonicalizer.TableInfo

extends Object
Class Inheritance
  • java.lang.Object
  • com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer.TableInfo

Immutable value class used for sharing information as efficiently as possible, by only require synchronization of reference manipulation but not access to contents.
Since
2.1

Field Summary

Modifier and TypeField and Description
public final int
public final int
public final int[]
public final String[]
public final int
public final int
public final int

Constructor Summary

AccessConstructor and Description
public
TableInfo(int size, int count, int tertiaryShift, int[] mainHash, String[] names, int spilloverEnd, int longNameOffset)

public

Method Summary

Modifier and TypeMethod and Description
public static ByteQuadsCanonicalizer.TableInfo
createInitial(int sz)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

countback to summary
public final int count
longNameOffsetback to summary
public final int longNameOffset
mainHashback to summary
public final int[] mainHash
namesback to summary
public final String[] names
sizeback to summary
public final int size
spilloverEndback to summary
public final int spilloverEnd
tertiaryShiftback to summary
public final int tertiaryShift

Constructor Detail

TableInfoback to summary
public TableInfo(int size, int count, int tertiaryShift, int[] mainHash, String[] names, int spilloverEnd, int longNameOffset)
TableInfoback to summary
public TableInfo(ByteQuadsCanonicalizer src)

Method Detail

createInitialback to summary
public static ByteQuadsCanonicalizer.TableInfo createInitial(int sz)