lib/serialization: intro DuplexCache
[nit.git] / lib / serialization / caching.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Services for caching serialization engines
16 module caching
17
18 import serialization
19 private import engine_tools
20
21 # A `Serializer` with a `cache`
22 abstract class CachingSerializer
23 super Serializer
24
25 # Cache of known objects
26 var cache = new SerializerCache is lazy, writable
27 end
28
29 # A `Deserializer` with a `cache`
30 abstract class CachingDeserializer
31 super Deserializer
32
33 # Cache of known objects
34 var cache = new DeserializerCache is lazy, writable
35 end
36
37 # Cache of sent objects
38 #
39 # Used by `Serializer` to avoid duplicating objects, by serializing them once,
40 # then using a reference.
41 class SerializerCache
42 # Map of already serialized objects to the reference id
43 private var sent: Map[Serializable, Int] = new StrictHashMap[Serializable, Int]
44
45 # Is `object` known?
46 fun has_object(object: Serializable): Bool do return sent.keys.has(object)
47
48 # Get the id for `object`
49 #
50 # Require: `has_object(object)`
51 fun id_for(object: Serializable): Int
52 do
53 assert sent.keys.has(object)
54 return sent[object]
55 end
56
57 # Get a new id for `object` and store it
58 #
59 # Require: `not has_object(object)`
60 fun new_id_for(object: Serializable): Int
61 do
62 var id = sent.length
63 sent[object] = id
64 return id
65 end
66 end
67
68 # Cache of received objects sorted by there reference id
69 #
70 # Used by `Deserializer` to find already deserialized objects by their reference.
71 class DeserializerCache
72 # Map of references to already deserialized objects.
73 private var received: Map[Int, Object] = new StrictHashMap[Int, Object]
74
75 # Is there an object associated to `id`?
76 fun has_id(id: Int): Bool do return received.keys.has(id)
77
78 # Get the object associated to `id`
79 fun object_for(id: Int): nullable Object do return received[id]
80
81 # Associate `object` to `id`
82 fun []=(id: Int, object: Object) do received[id] = object
83 end
84
85 # A shared cache for serialization and deserialization
86 class DuplexCache
87 super SerializerCache
88 super DeserializerCache
89
90 redef fun new_id_for(object)
91 do
92 var id = super
93 received[id] = object
94 return id
95 end
96
97 redef fun []=(id, object)
98 do
99 super
100 assert object isa Serializable
101 sent[object] = id
102 end
103 end