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)

File:
1 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  }
Note: See TracChangeset for help on using the changeset viewer.