@@ -39,9 +39,49 @@ import Streamly.Internal.Data.Serialize.TH.Common
3939-- Notes
4040--------------------------------------------------------------------------------
4141
42−-- Encoding the header length is required to check if we want to compare the
43−-- header. We should not compare the headers if the lengths of the headers are
44−-- not equal as this might lead to a runtime error.
42+-- Compatibility Algorithm
43+-- =======================
44+--
45+-- The algorithm is written without any low level implementation details. See
46+-- the code for any low level implementation details.
47+--
48+-- Serialization:
49+-- --------------
50+--
51+-- To serialize the data,
52+--
53+-- * Get the list of keys for the record as @keyList@.
54+-- * Serialize the @keyList@.
55+-- * Serialize the @fields@ one-by-one after serializing the @keyList@.
56+--
57+-- Deserialization:
58+-- ----------------
59+--
60+-- To deserialize the data to type @T@,
61+--
62+-- __Checking for type match__:
63+--
64+-- * Get the list of keys for type @T@ as @targetKeyList@.
65+-- * Get the list of keys encoded as @encodedKeyList@.
66+-- * If @targetKeyList == encodedKeyList@ see the __Type Match__ section else
67+-- see the __No Type Match__ section.
68+--
69+-- __Type Match__:
70+--
71+-- * Decode the fields one-by-one and construct the type @T@ in the end.
72+--
73+-- __No Type Match__:
74+--
75+-- * Decode the list of keys encoded into @encodedKeyList@.
76+-- * Get the list of keys for type @T@ as @targetKeyList@.
77+-- * Loop through @encodedKeyList@ and start deserializing the encoded data.
78+-- * If the key is present in @encodedKeyList@ and not in @targetKeyList@
79+-- then skip parsing the corresponding value.
80+-- * If the key is present in @targetKeyList@ and not in @encodedKeyList@
81+-- then set the value for that key as @Nothing@.
82+-- * If the key is present in both @encodedKeyList@ and in @targetKeyList@
83+-- parse the value.
84+-- * Construct @T@ after parsing all the data.
4585
4686--------------------------------------------------------------------------------
4787-- Compact lists
@@ -170,8 +210,9 @@ headerValue (SimpleDataCon _ fields) =
170210-- Peek
171211--------------------------------------------------------------------------------
172212
173−-- Encoding the size is required if we want to skip the field.
174−-- We encode the size as 'Word32' hence there is a 4 bytes increase in size.
213+-- Encoding the size is required if we want to skip the field without knowing
214+-- its type. We encode the size as 'Word32' hence there is a 4 bytes increase
215+-- in size.
175216{-# INLINE serializeWithSize #-}
176217serializeWithSize :: Serialize a => Int -> MutableByteArray -> a -> IO Int
177218serializeWithSize off arr val = do
@@ -182,6 +223,9 @@ serializeWithSize off arr val = do
182223mkSerializeExpr :: Name -> SimpleDataCon -> Q Exp
183224mkSerializeExpr initialOffset (con@(SimpleDataCon cname fields)) = do
184225 afterHLen <- newName "afterHLen"
226+ -- Encoding the header length is required.
227+ -- We first compare the header length encoded and the current header
228+ -- length. Only if the header lengths match, we compare the headers.
185229 [|do $(varP afterHLen) <-
186230 serialize
187231 ($(varE initialOffset) + 4)