A HashCollection is an array of HashNode[K] indexed by the K hash value

Introduced properties

private type N: HashNode[K]

core :: HashCollection :: N

private var _array: NativeArray[nullable N]

core :: HashCollection :: _array

private var _capacity: Int

core :: HashCollection :: _capacity

private var _first_item: nullable N

core :: HashCollection :: _first_item

private var _last_accessed_key: nullable Object

core :: HashCollection :: _last_accessed_key

The last key accessed (used for cache)
private var _last_accessed_node: nullable N

core :: HashCollection :: _last_accessed_node

The last node accessed (used for cache)
private var _last_item: nullable N

core :: HashCollection :: _last_item

private fun array: NativeArray[nullable N]

core :: HashCollection :: array

private fun array=(array: NativeArray[nullable N])

core :: HashCollection :: array=

private fun capacity: Int

core :: HashCollection :: capacity

private fun capacity=(capacity: Int)

core :: HashCollection :: capacity=

private fun enlarge(cap: Int)

core :: HashCollection :: enlarge

Force a capacity
private fun first_item: nullable N

core :: HashCollection :: first_item

private fun first_item=(first_item: nullable N)

core :: HashCollection :: first_item=

private fun gt_collide(i: Int, k: K)

core :: HashCollection :: gt_collide

Count and update length of collisions for node_at_idx
private fun index_at(k: nullable Object): Int

core :: HashCollection :: index_at

Return the index of the key k
private fun last_accessed_key: nullable Object

core :: HashCollection :: last_accessed_key

The last key accessed (used for cache)
private fun last_accessed_key=(last_accessed_key: nullable Object)

core :: HashCollection :: last_accessed_key=

The last key accessed (used for cache)
private fun last_accessed_node: nullable N

core :: HashCollection :: last_accessed_node

The last node accessed (used for cache)
private fun last_accessed_node=(last_accessed_node: nullable N)

core :: HashCollection :: last_accessed_node=

The last node accessed (used for cache)
private fun last_item: nullable N

core :: HashCollection :: last_item

private fun last_item=(last_item: nullable N)

core :: HashCollection :: last_item=

private fun node_at(k: nullable Object): nullable N

core :: HashCollection :: node_at

Return the node associated with the key
private fun node_at_idx(i: Int, k: nullable Object): nullable N

core :: HashCollection :: node_at_idx

Return the node associated with the key (but with the index already known)
private fun raz

core :: HashCollection :: raz

Clear the whole structure
private fun remove_node(k: nullable Object)

core :: HashCollection :: remove_node

Remove the node assosiated with the key
private fun st_collide(i: Int, n: N)

core :: HashCollection :: st_collide

Count and update length of collisions for store
private fun store(index: Int, node: N)

core :: HashCollection :: store

Add a new node at a given index
private fun the_length=(the_length: Int)

core :: HashCollection :: the_length=

Redefined properties

redef type SELF: HashCollection[K]

core $ HashCollection :: SELF

Type of this instance, automatically specialized in every class
redef fun enlarge(c: Int)

hash_debug :: hash_debug $ HashCollection :: enlarge

Force a capacity
redef fun node_at_idx(i: Int, k: nullable Object): nullable N

hash_debug :: hash_debug $ HashCollection :: node_at_idx

Return the node associated with the key (but with the index already known)
redef fun store(i: Int, n: N)

hash_debug :: hash_debug $ HashCollection :: store

Add a new node at a given index

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
private type N: HashNode[K]

core :: HashCollection :: N

type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _array: NativeArray[nullable N]

core :: HashCollection :: _array

private var _capacity: Int

core :: HashCollection :: _capacity

private var _first_item: nullable N

core :: HashCollection :: _first_item

private var _last_accessed_key: nullable Object

core :: HashCollection :: _last_accessed_key

The last key accessed (used for cache)
private var _last_accessed_node: nullable N

core :: HashCollection :: _last_accessed_node

The last node accessed (used for cache)
private var _last_item: nullable N

core :: HashCollection :: _last_item

private fun array: NativeArray[nullable N]

core :: HashCollection :: array

private fun array=(array: NativeArray[nullable N])

core :: HashCollection :: array=

private fun capacity: Int

core :: HashCollection :: capacity

private fun capacity=(capacity: Int)

core :: HashCollection :: capacity=

protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
private fun enlarge(cap: Int)

core :: HashCollection :: enlarge

Force a capacity
private fun first_item: nullable N

core :: HashCollection :: first_item

private fun first_item=(first_item: nullable N)

core :: HashCollection :: first_item=

fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
private fun gt_collide(i: Int, k: K)

core :: HashCollection :: gt_collide

Count and update length of collisions for node_at_idx
fun hash: Int

core :: Object :: hash

The hash code of the object.
private fun index_at(k: nullable Object): Int

core :: HashCollection :: index_at

Return the index of the key k
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
private fun last_accessed_key: nullable Object

core :: HashCollection :: last_accessed_key

The last key accessed (used for cache)
private fun last_accessed_key=(last_accessed_key: nullable Object)

core :: HashCollection :: last_accessed_key=

The last key accessed (used for cache)
private fun last_accessed_node: nullable N

core :: HashCollection :: last_accessed_node

The last node accessed (used for cache)
private fun last_accessed_node=(last_accessed_node: nullable N)

core :: HashCollection :: last_accessed_node=

The last node accessed (used for cache)
private fun last_item: nullable N

core :: HashCollection :: last_item

private fun last_item=(last_item: nullable N)

core :: HashCollection :: last_item=

private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
private fun node_at(k: nullable Object): nullable N

core :: HashCollection :: node_at

Return the node associated with the key
private fun node_at_idx(i: Int, k: nullable Object): nullable N

core :: HashCollection :: node_at_idx

Return the node associated with the key (but with the index already known)
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
private fun raz

core :: HashCollection :: raz

Clear the whole structure
private fun remove_node(k: nullable Object)

core :: HashCollection :: remove_node

Remove the node assosiated with the key
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
private fun st_collide(i: Int, n: N)

core :: HashCollection :: st_collide

Count and update length of collisions for store
private fun store(index: Int, node: N)

core :: HashCollection :: store

Add a new node at a given index
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
private fun the_length=(the_length: Int)

core :: HashCollection :: the_length=

abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
package_diagram core::hash_collection::HashCollection HashCollection core::Object Object core::hash_collection::HashCollection->core::Object core::HashMap HashMap core::HashMap->core::hash_collection::HashCollection core::HashSet HashSet core::HashSet->core::hash_collection::HashCollection core::HashMap... ... core::HashMap...->core::HashMap gamnit::TextureSet TextureSet gamnit::TextureSet->core::HashSet gamnit::SpriteSet SpriteSet gamnit::SpriteSet->core::HashSet nitc::FlowHashSet FlowHashSet nitc::FlowHashSet->core::HashSet gamnit::TextureSet... ... gamnit::TextureSet...->gamnit::TextureSet gamnit::SpriteSet... ... gamnit::SpriteSet...->gamnit::SpriteSet nitc::FlowHashSet... ... nitc::FlowHashSet...->nitc::FlowHashSet

Parents

interface Object

core :: Object

The root of the class hierarchy.

Children

class HashMap[K: nullable Object, V: nullable Object]

core :: HashMap

A Map implemented with a hash table.
class HashSet[E: nullable Object]

core :: HashSet

A Set implemented with a hash table.

Descendants

class AttributeMap

gamnit :: AttributeMap

Map to organize Attribute instances by their name
class AttributeMap

dot :: AttributeMap

Map of graph/node/edge attribute that can be rendered to dot.
private class BKNode

trees :: BKNode

A node that goes in a BKTree
class CmdOptions

nitc :: CmdOptions

Commands options
class DefaultMap[K: nullable Object, V: nullable Object]

more_collections :: DefaultMap

A map with a default value.
class FlowHashMap[K: nullable Object, V: nullable Object]

nitc :: FlowHashMap

A FlowSet based on a HashMap.
class FlowHashSet[E: nullable Object]

nitc :: FlowHashSet

A FlowSet based on a HashSet.
class IniFile

ini :: IniFile

Read and write INI configuration files
class IniSection

ini :: IniSection

A section in a IniFile
class JsonObject

json :: JsonObject

A JSON Object.
class MongoGroup

mongodb :: MongoGroup

Mongo pipeline group stage
class MongoMatch

mongodb :: MongoMatch

A basic match query
class MultiHashMap[K: nullable Object, V: nullable Object]

more_collections :: MultiHashMap

Simple way to store an HashMap[K, Array[V]]
class PRMap[V: nullable Object]

graph :: PRMap

Map each Vertice of a Digraph to it's PageRank.
class PerfMap

performance_analysis :: PerfMap

Collection of statistics on many events
private class QuickSearchTable

nitc :: QuickSearchTable

The result map for QuickSearch.
class ReadmeMetric

nitc :: ReadmeMetric

Readme metrics associated to a Package
class ReadmeMetrics

nitc :: ReadmeMetrics

All metrics about the readmes
abstract class ShaderVariableMap[A: ShaderVariable]

gamnit :: ShaderVariableMap

Map to organize ShaderVariable instances by their name
class SpriteSet

gamnit :: SpriteSet

Set of sprites sorting them into different SpriteContext
class StrictHashMap[K: nullable Object, V: nullable Object]

serialization :: StrictHashMap

Maps instances to a value, uses is_same_serialized and serialization_hash.
class TextureSet

gamnit :: TextureSet

Group of Texture
class UniformMap

gamnit :: UniformMap

Map to organize Uniform instances by their name
class Vector

vsm :: Vector

A n-dimensions vector

Class definitions

core $ HashCollection
# A HashCollection is an array of HashNode[K] indexed by the K hash value
private abstract class HashCollection[K]
	type N: HashNode[K]

	var array: NativeArray[nullable N] is noautoinit # Used to store items
	var capacity: Int = 0 # Size of _array
	var the_length: Int = 0 # Number of items in the map

	var first_item: nullable N = null # First added item (used to visit items in nice order)
	var last_item: nullable N = null # Last added item (same)

	# The last key accessed (used for cache)
	var last_accessed_key: nullable Object = null

	# The last node accessed (used for cache)
	var last_accessed_node: nullable N = null

	# Return the index of the key k
	fun index_at(k: nullable Object): Int
	do
		if k == null then return 0

		var i = k.hash % _capacity
		if i < 0 then i = - i
		return i
	end

	# Return the node associated with the key
	fun node_at(k: nullable Object): nullable N
	do
		if _the_length == 0 then return null
		# cache: `is` is used instead of `==` because it is a faster filter (even if not exact)
		if k.is_same_instance(_last_accessed_key) then return _last_accessed_node

		var res = node_at_idx(index_at(k), k)
		_last_accessed_key = k
		_last_accessed_node = res
		return res
	end

	# Return the node associated with the key (but with the index already known)
	fun node_at_idx(i: Int, k: nullable Object): nullable N
	do
		if _the_length == 0 then return null
		var c = _array[i]
		while c != null do
			var ck = c._key
			if ck.is_same_instance(k) or ck == k then # FIXME prefilter because the compiler is not smart enought yet
				break
			end
			c = c._next_in_bucklet
		end
		return c
	end

	# Add a new node at a given index
	fun store(index: Int, node: N)
	do
		# Store the item in the list
		if _first_item == null then
			_first_item = node
		else
			_last_item._next_item = node
		end
		node._prev_item = _last_item
		node._next_item = null
		_last_item = node

		# Then store it in the array
		var next = _array[index]
		_array[index] = node
		node._next_in_bucklet = next
		if next != null then next._prev_in_bucklet = node

		_last_accessed_key = node._key
		_last_accessed_node = node

		# Enlarge if needed
		var l = _the_length
		_the_length = l + 1

		# Magic values determined empirically
		# We do not want to enlarge too much
		# We also want a odd capacity so that the modulo is more distributive
		l = (l + 5) * 2 + 1
		if l >= _capacity then
			enlarge(l * 3 / 2 + 1)
		end
	end

	# Remove the node assosiated with the key
	fun remove_node(k: nullable Object)
	do
		if _the_length == 0 then return
		var i = index_at(k)
		var node = node_at_idx(i, k)
		if node == null then return

		# Remove the item in the list
		var prev = node._prev_item
		var next = node._next_item
		if prev != null then
			prev._next_item = next
		else
			_first_item = next
		end
		if next != null then
			next._prev_item = prev
		else
			_last_item = prev
		end

		# Remove the item in the array
		_the_length -= 1
		prev = node._prev_in_bucklet
		next = node._next_in_bucklet
		if prev != null then
			prev._next_in_bucklet = next
		else
			_array[i] = next
		end
		if next != null then
			next._prev_in_bucklet = prev
		end

		_last_accessed_key = null
	end

	# Clear the whole structure
	fun raz
	do
		var i = _capacity - 1
		while i >= 0 do
			_array[i] = null
			i -= 1
		end
		_the_length = 0
		_first_item = null
		_last_item = null
		_last_accessed_key = null
	end

	# Force a capacity
	fun enlarge(cap: Int)
	do
		# get a new capacity
		if cap < _the_length + 1 then cap = _the_length + 1
		if cap <= _capacity then return
		_capacity = cap
		_last_accessed_key = null

		# get a new array
		var new_array = new NativeArray[nullable N](cap)
		_array = new_array

		# Reput items in the array
		var node = _first_item
		while node != null do
			var index = index_at(node._key)
			# Then store it in the array
			var next = new_array[index]
			new_array[index] = node
			node._prev_in_bucklet = null
			node._next_in_bucklet = next
			if next != null then next._prev_in_bucklet = node
			node = node._next_item
		end
	end
end
lib/core/collection/hash_collection.nit:28,1--196,3

hash_debug :: hash_debug $ HashCollection
redef class HashCollection[K]
	redef fun node_at_idx(i,k)
	do
		sys.gt_count += 1
		sys.gt_tot_length += _the_length
		sys.gt_tot_cap += _capacity
		var c = _array[i]
		if c != null and c._next_in_bucklet != null then gt_collide(i,k)

		return super
	end

	redef fun enlarge(c)
	do
		super
		sys.en_count += 1
		sys.en_tot_length += _the_length
		sys.en_tot_cap += _capacity
	end

	# Count and update length of collisions for `node_at_idx`
	# Note for dynamic call-graph analysis: callers of this functions are
	# responsible of collisions.
	fun gt_collide(i: Int, k: K)
	do
		var c = _array[i]
		sys.gt_coll += 1
		while c != null do
			sys.gt_tot_coll += 1
			c = c._next_in_bucklet
		end
	end

	redef fun store(i, n)
	do
		sys.st_count += 1
		if _array[i] != null then st_collide(i,n)
		sys.st_tot_length += _the_length
		sys.st_tot_cap += _capacity

		super
	end

	# Count and update length of collisions for `store`
	# Note for dynamic call-graph analysis: callers of this functions are
	# responsible of collisions.
	fun st_collide(i: Int, n: N)
	do
		var c = _array[i]
		sys.st_coll += 1
		sys.st_tot_coll += 1
		while c != null do
			sys.st_tot_coll += 1
			c = c._next_in_bucklet
		end
	end
end
lib/hash_debug/hash_debug.nit:136,1--192,3