Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/11/10 15:50:50 (15 years ago)
Author:
epitzer
Message:

add support for type information interleaving and subsequently true streaming (#548)

Location:
trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs

    r3004 r3005  
    88using HeuristicLab.Tracing;
    99using HeuristicLab.Persistence.Core.Tokens;
     10using System.IO.Compression;
    1011
    1112namespace HeuristicLab.Persistence.Default.Xml {
     
    109110
    110111    protected override string Format(BeginToken beginToken) {
    111       return CreateNodeStart(
    112         XmlStringConstants.COMPOSITE,
    113         new Dictionary<string, object> {
     112      var dict = new Dictionary<string, object> {
    114113          {"name", beginToken.Name},
    115114          {"typeId", beginToken.TypeId},
    116           {"id", beginToken.Id}});
     115          {"id", beginToken.Id}};
     116      AddTypeInfo(beginToken.TypeId, dict);
     117      return CreateNodeStart(XmlStringConstants.COMPOSITE, dict);
     118       
     119    }
     120
     121    private void AddTypeInfo(int typeId, Dictionary<string, object> dict) {
     122      if (lastTypeToken != null) {
     123        if (typeId == lastTypeToken.Id) {
     124          dict.Add("typeName", lastTypeToken.TypeName);
     125          dict.Add("serializer", lastTypeToken.Serializer);
     126          lastTypeToken = null;
     127        } else {
     128          FlushTypeToken();
     129        }
     130      }
    117131    }
    118132
     
    122136
    123137    protected override string Format(PrimitiveToken dataToken) {
    124       return CreateNode(XmlStringConstants.PRIMITIVE,
    125         new Dictionary<string, object> {
     138      var dict = new Dictionary<string, object> {
    126139            {"typeId", dataToken.TypeId},
    127140            {"name", dataToken.Name},
    128             {"id", dataToken.Id}},
     141            {"id", dataToken.Id}};
     142      AddTypeInfo(dataToken.TypeId, dict);
     143      return CreateNode(XmlStringConstants.PRIMITIVE, dict,
    129144        ((XmlString)dataToken.SerialData).Data);
    130145    }
     
    149164    protected override string Format(MetaInfoEndToken metaInfoEndToken) {
    150165      return CreateNodeEnd(XmlStringConstants.METAINFO);
     166    }
     167
     168    private TypeToken lastTypeToken;
     169    protected override string Format(TypeToken token) {
     170      lastTypeToken = token;
     171      return "";
     172    }
     173
     174    private string FlushTypeToken() {
     175      if (lastTypeToken == null)
     176        return "";
     177      try {
     178        return CreateNode(XmlStringConstants.TYPE,
     179          new Dictionary<string, object> {
     180          {"id", lastTypeToken.Id},
     181          {"typeName", lastTypeToken.TypeName },
     182          {"serializer", lastTypeToken.Serializer }});
     183      } finally {
     184        lastTypeToken = null;
     185      }
    151186    }
    152187
     
    182217    }
    183218
    184 
    185219    public static void Serialize(object obj, string filename, Configuration config) {
    186220      Serialize(obj, filename, config, false, 5);
     
    192226        DateTime start = DateTime.Now;
    193227        using (FileStream stream = File.Create(tempfile)) {
    194           Serialize(obj, stream, config, includeAssemblies, compression);
     228          Serializer serializer = new Serializer(obj, config);
     229          serializer.InterleaveTypeInformation = false;
     230          XmlGenerator generator = new XmlGenerator();
     231          using (ZipOutputStream zipStream = new ZipOutputStream(stream)) {
     232            zipStream.IsStreamOwner = false;
     233            zipStream.SetLevel(compression);
     234            zipStream.PutNextEntry(new ZipEntry("data.xml") { DateTime = DateTime.MinValue });
     235            StreamWriter writer = new StreamWriter(zipStream);
     236            foreach (ISerializationToken token in serializer) {
     237              string line = generator.Format(token);
     238              writer.Write(line);
     239            }
     240            writer.Flush();
     241            zipStream.PutNextEntry(new ZipEntry("typecache.xml") { DateTime = DateTime.MinValue });
     242            foreach (string line in generator.Format(serializer.TypeCache)) {
     243              writer.Write(line);
     244            }
     245            writer.Flush();
     246            if (includeAssemblies) {
     247              foreach (string name in serializer.RequiredFiles) {
     248                Uri uri = new Uri(name);
     249                if (!uri.IsFile) {
     250                  Logger.Warn("cannot read non-local files");
     251                  continue;
     252                }
     253                zipStream.PutNextEntry(new ZipEntry(Path.GetFileName(uri.PathAndQuery)));
     254                FileStream reader = File.OpenRead(uri.PathAndQuery);
     255                byte[] buffer = new byte[1024 * 1024];
     256                while (true) {
     257                  int bytesRead = reader.Read(buffer, 0, 1024 * 1024);
     258                  if (bytesRead == 0)
     259                    break;
     260                  zipStream.Write(buffer, 0, bytesRead);
     261                }
     262                writer.Flush();
     263              }
     264            }
     265          }
    195266        }
    196267        Logger.Info(String.Format("serialization took {0} seconds with compression level {1}",
     
    204275    }
    205276
     277    public static void Serialize(object obj, Stream stream) {
     278      Serialize(obj, stream, ConfigurationService.Instance.GetConfiguration(new XmlFormat()));
     279    }
     280
    206281
    207282    public static void Serialize(object obj, Stream stream, Configuration config) {
    208283      Serialize(obj, stream, config, false);
    209284    }
    210    
     285
    211286    public static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies) {
    212       Serialize(obj, stream, config, includeAssemblies, 9);
    213     }
    214 
    215     public static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies, int compression) {     
     287      Serialize(obj, stream, config, includeAssemblies, true);
     288    }
     289
     290    public static void Serialize(object obj, Stream stream, Configuration config, bool includeAssemblies, bool interleaveTypeInfo) {     
    216291      try {
    217         Serializer serializer = new Serializer(obj, config);
    218         XmlGenerator generator = new XmlGenerator();
    219         using (ZipOutputStream zipStream = new ZipOutputStream(stream)) {
    220           zipStream.IsStreamOwner = false;
    221           zipStream.SetLevel(compression);
    222           zipStream.PutNextEntry(new ZipEntry("data.xml") { DateTime = DateTime.MinValue });
    223           StreamWriter writer = new StreamWriter(zipStream);
     292        using (StreamWriter writer = new StreamWriter(new GZipStream(stream, CompressionMode.Compress))) {
     293          Serializer serializer = new Serializer(obj, config);
     294          serializer.InterleaveTypeInformation = true;
     295          XmlGenerator generator = new XmlGenerator();
    224296          foreach (ISerializationToken token in serializer) {
    225297            string line = generator.Format(token);
     
    227299          }
    228300          writer.Flush();
    229           zipStream.PutNextEntry(new ZipEntry("typecache.xml") { DateTime = DateTime.MinValue });
    230           foreach (string line in generator.Format(serializer.TypeCache)) {
    231             writer.Write(line);
    232           }
    233           writer.Flush();
    234           if (includeAssemblies) {
    235             foreach (string name in serializer.RequiredFiles) {
    236               Uri uri = new Uri(name);
    237               if (!uri.IsFile) {
    238                 Logger.Warn("cannot read non-local files");
    239                 continue;
    240               }
    241               zipStream.PutNextEntry(new ZipEntry(Path.GetFileName(uri.PathAndQuery)));
    242               FileStream reader = File.OpenRead(uri.PathAndQuery);
    243               byte[] buffer = new byte[1024 * 1024];
    244               while (true) {
    245                 int bytesRead = reader.Read(buffer, 0, 1024 * 1024);
    246                 if (bytesRead == 0)
    247                   break;
    248                 zipStream.Write(buffer, 0, bytesRead);
    249               }
    250               writer.Flush();
    251             }
    252           }
    253301        }
    254302      } catch (PersistenceException) {
     
    256304      } catch (Exception e) {
    257305        throw new PersistenceException("Unexpected exception during Serialization.", e);
    258       }     
     306      }
    259307    }
    260308  }
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs

    r2874 r3005  
    88using ICSharpCode.SharpZipLib.Zip;
    99using HeuristicLab.Persistence.Core.Tokens;
     10using System.IO.Compression;
    1011
    1112namespace HeuristicLab.Persistence.Default.Xml {
     
    3031                     {XmlStringConstants.NULL, ParseNull},
    3132                     {XmlStringConstants.METAINFO, ParseMetaInfo},
     33                     {XmlStringConstants.TYPE, ParseTypeInfo},
    3234                   };
    3335    }
     
    5961      string name = reader.GetAttribute("name");
    6062      int typeId = int.Parse(reader.GetAttribute("typeId"));
     63      string typeName = reader.GetAttribute("typeName");
     64      string serializer = reader.GetAttribute("serializer");
     65      if (typeName != null)
     66        yield return new TypeToken(typeId, typeName, serializer);
    6167      XmlReader inner = reader.ReadSubtree();
    6268      inner.Read();
     
    7379        id = int.Parse(idString);
    7480      int typeId = int.Parse(reader.GetAttribute("typeId"));
     81      string typeName = reader.GetAttribute("typeName");
     82      string serializer = reader.GetAttribute("serializer");
     83      if (typeName != null)
     84        yield return new TypeToken(typeId, typeName, serializer);
    7585      yield return new BeginToken(name, typeId, id);
    7686      IEnumerator<ISerializationToken> iterator = GetEnumerator();
     
    96106        yield return iterator.Current;
    97107      yield return new MetaInfoEndToken();
     108    }
     109
     110    private IEnumerator<ISerializationToken> ParseTypeInfo() {
     111      yield return new TypeToken(
     112        int.Parse(reader.GetAttribute("id")),
     113        reader.GetAttribute("typeName"),
     114        reader.GetAttribute("serializer"));
    98115    }
    99116
     
    129146
    130147    public static object Deserialize(Stream stream) {
    131       using (ZipFile file = new ZipFile(stream)) {
    132         return Deserialize(file);
     148      try {
     149        using (StreamReader reader = new StreamReader(new GZipStream(stream, CompressionMode.Decompress))) {
     150          XmlParser parser = new XmlParser(reader);
     151          Deserializer deserializer = new Deserializer(new TypeMapping[] { });
     152          return deserializer.Deserialize(parser);
     153        }
     154      } catch (PersistenceException) {
     155        throw;
     156      } catch (Exception x) {
     157        throw new PersistenceException("Unexpected exception during deserialization", x);
    133158      }
    134159    }
     
    136161    private static object Deserialize(ZipFile zipFile) {
    137162      try {
    138         Deserializer deSerializer = new Deserializer(
    139           ParseTypeCache(
    140           new StreamReader(
    141             zipFile.GetInputStream(zipFile.GetEntry("typecache.xml")))));
     163        ZipEntry typecache = zipFile.GetEntry("typecache.xml");
     164        if (typecache == null)
     165          throw new PersistenceException("file does not contain typecache.xml");
     166        Deserializer deSerializer = new Deserializer(ParseTypeCache(new StreamReader(zipFile.GetInputStream(typecache))));
     167        ZipEntry data = zipFile.GetEntry("data.xml");
     168        if (data == null)
     169          throw new PersistenceException("file does not contain data.xml");
    142170        XmlParser parser = new XmlParser(
    143           new StreamReader(zipFile.GetInputStream(zipFile.GetEntry("data.xml"))));
     171          new StreamReader(zipFile.GetInputStream(data)));
    144172        object result = deSerializer.Deserialize(parser);
    145173        zipFile.Close();
    146174        return result;
    147       } catch (PersistenceException e) {
     175      } catch (PersistenceException) {
    148176        throw;
    149177      } catch (Exception e) {
Note: See TracChangeset for help on using the changeset viewer.