+
+class TypingHasher[E: Object]
+ super PerfectHasher[E, E]
+ super TypingLayoutBuilder[E]
+
+ var mmodule: MModule
+
+ init(operator: PHOperator, mmodule: MModule) do
+ super(operator)
+ self.mmodule = mmodule
+ end
+
+ redef fun build_layout(elements: Set[E]): PHLayout[E, E] do
+ var result = new PHLayout[E, E]
+ var conflicts = self.build_conflicts(elements)
+ result.ids = self.compute_ids(elements)
+ result.masks = self.compute_masks(conflicts, result.ids)
+ result.hashes = self.compute_hashes(conflicts, result.ids, result.masks)
+ return result
+ end
+
+ # Ids start from 1 instead of 0
+ private fun compute_ids(elements: Set[E]): Map[E, Int] do
+ var ids = new HashMap[E, Int]
+ var lin = self.reverse_linearize(elements)
+ for e in lin do
+ ids[e] = ids.length + 1
+ end
+ return ids
+ end
+
+ private fun build_conflicts(elements: Set[E]): Map[E, Set[E]] do
+ var conflicts = new HashMap[E, Set[E]]
+ for e in elements do
+ var supers = self.super_elements(e, elements)
+ supers.add(e)
+ conflicts[e] = supers
+ end
+ return conflicts
+ end
+
+ private fun super_elements(element: E, elements: Set[E]): Set[E] is abstract
+ private fun reverse_linearize(elements: Set[E]): Array[E] is abstract
+end
+
+class MTypeHasher
+ super TypingHasher[MType]
+
+ init(operator: PHOperator, mmodule: MModule) do super(operator, mmodule)
+
+ redef fun super_elements(element, elements) do
+ return self.mmodule.super_mtypes(element, elements)
+ end
+
+ redef fun reverse_linearize(elements) do
+ return self.mmodule.reverse_linearize_mtypes(elements)
+ end
+end
+
+class MClassHasher
+ super TypingHasher[MClass]
+
+ init(operator: PHOperator, mmodule: MModule) do super(operator, mmodule)
+
+ redef fun super_elements(element, elements) do
+ return self.mmodule.super_mclasses(element)
+ end
+
+ redef fun reverse_linearize(elements) do
+ return self.mmodule.reverse_linearize_mclasses(elements)
+ end
+end
+
+# Layout builder for MProperty using Perfect Hashing (PH)
+# TODO implement this class without sublcassing CL builder
+class MPropertyHasher[E: MProperty]
+ super MPropertyColorer[E]
+end
+
+class ResolutionHasher
+ super PerfectHasher[MClassType, MType]
+ super ResolutionLayoutBuilder
+
+ init(operator: PHOperator) do super(operator)
+
+ # Compute resolved types masks and hashes
+ redef fun build_layout(elements) do
+ var result = new PHLayout[MClassType, MType]
+ var ids = new HashMap[MType, Int]
+ var color = 1
+ for mclasstype, mclasstypes in elements do
+ for element in mclasstypes do
+ if ids.has_key(element) then continue
+ ids[element] = color
+ color += 1
+ end
+ end
+ result.ids = ids
+ result.pos = ids
+ result.masks = self.compute_masks(elements, ids)
+ result.hashes = self.compute_hashes(elements, ids, result.masks)
+ return result
+ end
+end