compiling: moves up the compiling_writer module to be used by the new FFI
[nit.git] / src / coloring.nit
index 4e4805d..57ca211 100644 (file)
@@ -774,6 +774,135 @@ class VTColoring
        init(class_coloring: ClassColoring) do end
 end
 
+class NaiveVTColoring
+       super VTColoring
+
+       init(class_coloring: ClassColoring) do end
+
+       redef fun colorize: Map[MPROP, Int] do
+               var mclasses = new HashSet[MClass]
+               mclasses.add_all(self.class_coloring.core)
+               mclasses.add_all(self.class_coloring.crown)
+               var min_color = 0
+
+               for mclass in mclasses do
+                       min_color = max_color(min_color, mclasses)
+                       colorize_elements(self.properties(mclass), min_color)
+               end
+               return self.coloration_result
+       end
+end
+
+abstract class VTPerfectHashing
+       super VTColoring
+
+       private var masks: Map[MClass, Int] = new HashMap[MClass, Int]
+
+       init(class_coloring: ClassColoring) do end
+
+       redef fun colorize: Map[MPROP, Int] do
+               var mclasses = new HashSet[MClass]
+               mclasses.add_all(self.class_coloring.core)
+               mclasses.add_all(self.class_coloring.crown)
+               for mclass in mclasses do
+                       var vts = self.properties(mclass)
+                       for vt in vts do
+                               if coloration_result.has_key(vt) then continue
+                               coloration_result[vt] = coloration_result.length + 1
+                       end
+               end
+               return self.coloration_result
+       end
+
+       fun compute_masks: Map[MClass, Int] do
+               var mclasses = new HashSet[MClass]
+               mclasses.add_all(self.class_coloring.core)
+               mclasses.add_all(self.class_coloring.crown)
+               for mclass in mclasses do
+                       self.masks[mclass] = compute_mask(self.properties(mclass))
+               end
+               return self.masks
+       end
+
+       private fun compute_mask(vts: Set[MPROP]): Int do
+               var mask = 0
+               loop
+                       var used = new List[Int]
+                       for vt in vts do
+                               var res = op(mask, self.coloration_result[vt])
+                               if used.has(res) then
+                                       break
+                               else
+                                       used.add(res)
+                               end
+                       end
+                       if used.length == vts.length then break
+                       mask += 1
+               end
+               return mask
+       end
+
+       redef fun build_property_tables do
+               var tables = new HashMap[MClass, Array[nullable MPROPDEF]]
+
+               for mclass in self.class_coloring.coloration_result.keys do
+                       var table = new Array[nullable MPROPDEF]
+                       # first, fill table from parents by reverse linearization order
+                       var parents = new OrderedSet[MClass]
+                       parents.add_all(self.class_coloring.super_elements(mclass))
+                       self.class_coloring.reverse_sorter.sort(parents)
+                       for parent in parents do
+                               for mproperty in self.properties(parent) do
+                                       var color = phash(self.coloration_result[mproperty], masks[mclass])
+                                       if table.length <= color then
+                                               for i in [table.length .. color[ do
+                                                       table[i] = null
+                                               end
+                                       end
+                                       for mpropdef in mproperty.mpropdefs do
+                                               if mpropdef.mclassdef.mclass == parent then
+                                                       table[color] = mpropdef
+                                               end
+                                       end
+                               end
+                       end
+
+                       # then override with local properties
+                       for mproperty in self.properties(mclass) do
+                               var color = phash(self.coloration_result[mproperty], masks[mclass])
+                               if table.length <= color then
+                                       for i in [table.length .. color[ do
+                                               table[i] = null
+                                       end
+                               end
+                               for mpropdef in mproperty.mpropdefs do
+                                       if mpropdef.mclassdef.mclass == mclass then
+                                               table[color] = mpropdef
+                                       end
+                               end
+                       end
+                       tables[mclass] = 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 VTModPerfectHashing
+       super VTPerfectHashing
+       init(class_coloring: ClassColoring) do end
+       redef fun op(mask, id) do return mask % id
+end
+
+class VTAndPerfectHashing
+       super VTPerfectHashing
+       init(class_coloring: ClassColoring) do end
+       redef fun op(mask, id) do return mask.bin_and(id)
+end
+
 # MParameterType coloring
 class FTColoring
        private var class_coloring: ClassColoring
@@ -896,6 +1025,128 @@ class FTColoring
        end
 end
 
+class NaiveFTColoring
+       super FTColoring
+
+       init(class_coloring: ClassColoring) do end
+
+       redef fun colorize: Map[MParameterType, Int] do
+               var mclasses = new HashSet[MClass]
+               mclasses.add_all(self.class_coloring.core)
+               mclasses.add_all(self.class_coloring.crown)
+               var min_color = 0
+
+               for mclass in mclasses do
+                       min_color = max_color(min_color, mclasses)
+                       colorize_elements(self.fts(mclass), min_color)
+               end
+               return self.coloration_result
+       end
+end
+
+abstract class FTPerfectHashing
+       super FTColoring
+
+       private var masks: Map[MClass, Int] = new HashMap[MClass, Int]
+
+       init(class_coloring: ClassColoring) do end
+
+       redef fun colorize: Map[MParameterType, Int] do
+               var mclasses = new HashSet[MClass]
+               mclasses.add_all(self.class_coloring.core)
+               mclasses.add_all(self.class_coloring.crown)
+               for mclass in mclasses do
+                       for ft in self.fts(mclass) do
+                               if coloration_result.has_key(ft) then continue
+                               coloration_result[ft] = coloration_result.length + 1
+                       end
+               end
+               return self.coloration_result
+       end
+
+       fun compute_masks: Map[MClass, Int] do
+               var mclasses = new HashSet[MClass]
+               mclasses.add_all(self.class_coloring.core)
+               mclasses.add_all(self.class_coloring.crown)
+               for mclass in mclasses do
+                       var fts = new HashSet[MParameterType]
+                       for parent in self.class_coloring.super_elements(mclass) do
+                               fts.add_all(self.fts(parent))
+                       end
+                       fts.add_all(self.fts(mclass))
+                       self.masks[mclass] = compute_mask(fts)
+               end
+               return self.masks
+       end
+
+       private fun compute_mask(fts: Set[MParameterType]): Int do
+               var mask = 0
+               loop
+                       var used = new List[Int]
+                       for ft in fts do
+                               var res = op(mask, self.coloration_result[ft])
+                               if used.has(res) then
+                                       break
+                               else
+                                       used.add(res)
+                               end
+                       end
+                       if used.length == fts.length then break
+                       mask += 1
+               end
+               return mask
+       end
+
+       redef fun build_ft_tables do
+               var tables = new HashMap[MClass, Array[nullable MParameterType]]
+
+               for mclass in self.class_coloring.coloration_result.keys do
+                       var table = new Array[nullable MParameterType]
+
+                       # first, fill table from parents
+                       for parent in self.class_coloring.super_elements(mclass) do
+                               for ft in self.fts(parent) do
+                                       var color = phash(self.coloration_result[ft], masks[mclass])
+                                       if table.length <= color then
+                                               for i in [table.length .. color[ do
+                                                       table[i] = null
+                                               end
+                                       end
+                                       table[color] = ft
+                               end
+                       end
+
+                       # then override with local properties
+                       for ft in self.fts(mclass) do
+                               var color = phash(self.coloration_result[ft], masks[mclass])
+                               if table.length <= color then
+                                       for i in [table.length .. color[ do
+                                               table[i] = null
+                                       end
+                               end
+                               table[color] = ft
+                       end
+                       tables[mclass] = 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 FTModPerfectHashing
+       super FTPerfectHashing
+       init(class_coloring: ClassColoring) do end
+       redef fun op(mask, id) do return mask % id
+end
+
+class FTAndPerfectHashing
+       super FTPerfectHashing
+       init(class_coloring: ClassColoring) do end
+       redef fun op(mask, id) do return mask.bin_and(id)
+end
+
 # Live Entries coloring
 class LiveEntryColoring
 
@@ -1042,18 +1293,206 @@ class LiveEntryColoring
 
        private fun add_conflict(mtype: MType, otype: MType) do
                if mtype == otype then return
-               if not self.conflicts_graph_cache.has_key(mtype) then  self.conflicts_graph_cache[mtype] = new HashSet[MClassType]
+               if not self.conflicts_graph_cache.has_key(mtype) then  self.conflicts_graph_cache[mtype] = new HashSet[MType]
                self.conflicts_graph_cache[mtype].add(otype)
-               if not self.conflicts_graph_cache.has_key(otype) then  self.conflicts_graph_cache[otype] = new HashSet[MClassType]
+               if not self.conflicts_graph_cache.has_key(otype) then  self.conflicts_graph_cache[otype] = new HashSet[MType]
                self.conflicts_graph_cache[otype].add(mtype)
        end
        private fun conflicts_graph: Map[MType, Set[MType]] do return conflicts_graph_cache.as(not null)
 end
 
+class NaiveLiveEntryColoring
+       super LiveEntryColoring
+
+       init do end
+
+       redef fun colorize_elements(elements: Collection[MType]) do
+               var color = 0
+               for element in elements do
+                       coloration_result[element] = color
+                       color += 1
+               end
+       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
+
+       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 = self.coloration_result[mtype]
+                               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
+
+       # 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
+
+       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
 
 # An ordered set
-class OrderedSet[E]
+class OrderedSet[E: Object]
        super Array[E]
 
        init do end
@@ -1079,4 +1518,4 @@ class OrderedSet[E]
        fun linearize(sorter: AbstractSorter[E]) do
                sorter.sort(self)
        end
-end
\ No newline at end of file
+end