Merge: doc: fixed some typos and other misc. corrections
[nit.git] / lib / serialization / engine_tools.nit
index 1e0ee0b..bd4b417 100644 (file)
 # Advanced services for serialization engines
 module engine_tools
 
-import serialization
+import serialization_core
+intrude import core::collection::hash_collection
 
-# Maps instances to a value, uses `is_same_instance`
-#
-# Warning: This class does not implement all the services from `Map`.
+# Maps instances to a value, uses `is_same_serialized` and `serialization_hash`.
 class StrictHashMap[K, V]
-       super Map[K, V]
-
-       # private
-       var map = new HashMap[K, Array[Couple[K, V]]]
+       super HashMap[K, V]
 
-       redef var length = 0
+       redef fun index_at(k)
+       do
+               if k == null then return 0
 
-       redef fun is_empty do return length == 0
+               var i = k.serialization_hash % _capacity
+               if i < 0 then i = - i
+               return i
+       end
 
-       # private
-       fun node_at(key: K): nullable Couple[K, V]
+       redef fun node_at_idx(i, k)
        do
-               if not map.keys.has(key) then return null
-
-               var arr = map[key]
-               for couple in arr do
-                       if couple.first.is_same_serialized(key) then
-                               return couple
+               var c = _array[i]
+               while c != null do
+                       var ck = c._key
+                       assert ck != null
+                       if ck.is_same_serialized(k) then
+                               break
                        end
+                       c = c._next_in_bucklet
                end
-
-               return null
+               return c
        end
+end
+
+redef interface Object
+       # Is `self` the same as `other` in a serialization context?
+       #
+       # Used to determine if an object has already been serialized.
+       fun is_same_serialized(other: nullable Object): Bool do return is_same_instance(other)
 
-       redef fun [](key)
+       # Hash value use for serialization
+       #
+       # Used in combination with `is_same_serialized`. If two objects are the same
+       # in a serialization context, they must have the same `serialization_hash`.
+       fun serialization_hash: Int do return object_id
+end
+
+redef class String
+       redef fun serialization_hash do return hash
+       redef fun is_same_serialized(o) do return self == o
+end
+
+redef class Text
+
+       # Strip the `nullable` prefix from the type name `self`
+       #
+       # ~~~
+       # assert "String".strip_nullable == "String"
+       # assert "nullable Array[Int]".strip_nullable == "Array[Int]"
+       # assert "Map[Set[String], Set[Int]]".strip_nullable == "Map[Set[String], Set[Int]]"
+       # ~~~
+       fun strip_nullable: Text
        do
-               var node = node_at(key)
-               assert node != null
-               return node.second
+               var prefix = "nullable "
+               return if has_prefix(prefix) then substring_from(prefix.length) else self
        end
 
-       redef fun []=(key, value)
+       # Strip the `nullable` prefix and the params from the type name `self`
+       #
+       # ~~~
+       # assert "String".strip_nullable_and_params == "String"
+       # assert "nullable Array[Int]".strip_nullable_and_params == "Array"
+       # assert "Map[Set[String], Set[Int]]".strip_nullable_and_params == "Map"
+       # ~~~
+       fun strip_nullable_and_params: Text
        do
-               var node = node_at(key)
-               if node != null then
-                       node.second = value
-                       return
-               end
+               var class_name = strip_nullable
 
-               var arr
-               if not map.keys.has(key) then
-                       arr = new Array[Couple[K, V]]
-                       map[key] = arr
-               else arr = map[key]
-
-               arr.add new Couple[K, V](key, value)
-               self.length += 1
+               var bracket_index = class_name.index_of('[')
+               if bracket_index == -1 then return class_name
+               return class_name.substring(0, bracket_index)
        end
-
-       redef fun has_key(key) do return node_at(key) != null
 end