- fun compute_masks(elements: Map[MClassType, Set[MType]]): Map[MClassType, Int] do
- for mclasstype, mtypes in elements do
- self.masks[mclasstype] = compute_mask(mtypes)
- end
- return self.masks
- end
-
- private fun compute_mask(mtypes: Set[MType]): Int do
- var mask = 0
- loop
- var used = new List[Int]
- for mtype in mtypes do
- var res = op(mask, self.coloration_result[mtype])
- if used.has(res) then
- break
- else
- used.add(res)
- end
- end
- if used.length == mtypes.length then break
- mask += 1
- end
- return mask
- end
-
- redef fun build_tables(elements: Map[MClassType, Set[MType]]): Map[MClassType, Array[nullable MType]] do
- var tables = new HashMap[MClassType, Array[nullable MType]]
-
- for mclasstype, mtypes in elements do
- var table = new Array[nullable MType]
- for mtype in mtypes do
- var color = phash(self.coloration_result[mtype], masks[mclasstype])
- if table.length <= color then
- for i in [table.length .. color[ do
- table[i] = null
- end
- end
- table[color] = mtype
- end
- tables[mclasstype] = table
- end
- return tables
- end
-
- private fun op(mask: Int, id:Int): Int is abstract
- private fun phash(id: Int, mask: Int): Int do return op(mask, id)
-end
-
-class UnanchoredTypeModPerfectHashing
- super UnanchoredTypePerfectHashing
- init do end
- redef fun op(mask, id) do return mask % id
-end
-
-class UnanchoredTypeAndPerfectHashing
- super UnanchoredTypePerfectHashing
- init do end
- redef fun op(mask, id) do return mask.bin_and(id)
-end
-
-
-# Utils
-
-redef class HashSet[E]
- init from(elements: Collection[E]) do
- init
- self.add_all(elements)
- end
-end
-
-redef class Array[E]
- init from(elements: Collection[E]) do
- init
- self.add_all(elements)
- end
-
- # Return a new Array with the elements only contened in 'self' and not in 'o'
- fun -(o: Array[E]): Array[E] do
- var res = new Array[E]
- for e in self do if not o.has(e) then res.add(e)
- return res
- end
-end
-
-redef class MModule
-
- # Return a linearization of a set of mtypes
- private fun linearize_mtypes(mtypes: Set[MType]): Array[MType] do
- var lin = new Array[MType].from(mtypes)
- var sorter = new TypeSorter(self)
- sorter.sort(lin)
- return lin
- end
-
- # Return a reverse linearization of a set of mtypes
- private fun reverse_linearize_mtypes(mtypes: Set[MType]): Array[MType] do
- var lin = new Array[MType].from(mtypes)
- var sorter = new ReverseTypeSorter(self)
- sorter.sort(lin)
- return lin
- end
-
- # Return super types of a `mtype` in `self`
- private fun super_mtypes(mtype: MType, mtypes: Set[MType]): Set[MType] do
- if not self.super_mtypes_cache.has_key(mtype) then
- var supers = new HashSet[MType]
- for otype in mtypes do
- if otype == mtype then continue
- if mtype.is_subtype(self, null, otype) then
- supers.add(otype)
- end
- end
- self.super_mtypes_cache[mtype] = supers
- end
- return self.super_mtypes_cache[mtype]
- end
-
- private var super_mtypes_cache: Map[MType, Set[MType]] = new HashMap[MType, Set[MType]]
-
- # Return all sub mtypes (directs and indirects) of a `mtype` in `self`
- private fun sub_mtypes(mtype: MType, mtypes: Set[MType]): Set[MType] do
- if not self.sub_mtypes_cache.has_key(mtype) then
- var subs = new HashSet[MType]
- for otype in mtypes do
- if otype == mtype then continue
- if otype.is_subtype(self, null, mtype) then
- subs.add(otype)
- end
- end
- self.sub_mtypes_cache[mtype] = subs
- end
- return self.sub_mtypes_cache[mtype]
- end
-
- private var sub_mtypes_cache: Map[MType, Set[MType]] = new HashMap[MType, Set[MType]]
-
- # Return a linearization of a set of mclasses
- private fun linearize_mclasses(mclasses: Set[MClass]): Array[MClass] do
- var lin = new Array[MClass].from(mclasses)
- var sorter = new ClassSorter(self)
- sorter.sort(lin)
- return lin
- end
-
- # Return a reverse linearization of a set of mtypes
- private fun reverse_linearize_mclasses(mclasses: Set[MClass]): Array[MClass] do
- var lin = new Array[MClass].from(mclasses)
- var sorter = new ReverseClassSorter(self)
- sorter.sort(lin)
- return lin
- end
-
- # Return all super mclasses (directs and indirects) of a `mclass` in `self`
- private fun super_mclasses(mclass: MClass): Set[MClass] do
- if not self.super_mclasses_cache.has_key(mclass) then
- var supers = new HashSet[MClass]
- if self.flatten_mclass_hierarchy.has(mclass) then
- for sup in self.flatten_mclass_hierarchy[mclass].greaters do
- if sup == mclass then continue
- supers.add(sup)
- end
- end
- self.super_mclasses_cache[mclass] = supers