end
end
-# live unanchored coloring
-class UnanchoredTypeColoring
-
- private var coloration_result: Map[MType, Int] = new HashMap[MType, Int]
- private var conflicts_graph: Map[MType, Set[MType]] = new HashMap[MType, Set[MType]]
-
- init do end
-
- fun colorize(elements: Map[MClassType, Set[MType]]): Map[MType, Int] do
- build_conflicts_graph(elements)
- colorize_elements(elements)
- return coloration_result
- end
-
- # Colorize a collection of elements
- fun colorize_elements(elements: Map[MClassType, Set[MType]]) do
- var min_color = 0
- for mclasstype, mclasstypes in elements do
- for element in mclasstypes do
- if self.coloration_result.has_key(element) then continue
- var color = min_color
- while not self.is_color_free(element, color) do
- color += 1
- end
- coloration_result[element] = color
- color = min_color
- end
- end
- end
-
- # Check if a related element to the element already use the color
- private fun is_color_free(element: MType, color: Int): Bool do
- if conflicts_graph.has_key(element) then
- for st in conflicts_graph[element] do
- if coloration_result.has_key(st) and coloration_result[st] == color then return false
- end
- end
- return true
- end
-
- # look for unanchored types generated by the same type
- private fun build_conflicts_graph(elements: Map[MClassType, Set[MType]]) do
- for mclasstype, mtypes in elements do
- for mtype in mtypes do
- for otype in mtypes do
- if otype == mtype then continue
- self.add_conflict(mtype, otype)
- end
- end
- end
- end
-
- private fun add_conflict(mtype: MType, otype: MType) do
- if mtype == otype then return
- if not self.conflicts_graph.has_key(mtype) then self.conflicts_graph[mtype] = new HashSet[MType]
- self.conflicts_graph[mtype].add(otype)
- if not self.conflicts_graph.has_key(otype) then self.conflicts_graph[otype] = new HashSet[MType]
- self.conflicts_graph[otype].add(mtype)
- end
-end
-
-class NaiveUnanchoredTypeColoring
- super UnanchoredTypeColoring
-
- init do end
-
- redef fun colorize_elements(elements: Map[MClassType, Set[MType]]) do
- var color = 0
- for mclasstype, mclasstypes in elements do
- for element in mclasstypes do
- coloration_result[element] = color
- color += 1
- end
- end
- end
-end
-
-abstract class UnanchoredTypePerfectHashing
- super NaiveUnanchoredTypeColoring
-
- private var masks: Map[MClassType, Int] = new HashMap[MClassType, Int]
-
- init do end
-
- redef fun colorize_elements(elements: Map[MClassType, Set[MType]]) do
- var color = 1
- for mclasstype, mclasstypes in elements do
- for element in mclasstypes do
- coloration_result[element] = color
- color += 1
- end
- end
- end
-
- 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
-
- 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]