Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs @ 13358

Last change on this file since 13358 was 13358, checked in by swagner, 8 years ago

#2520: Worked on new persistence implementation

File size: 4.9 KB
RevLine 
[13326]1#region License Information
2/* HeuristicLab
[13347]3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[13326]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.PluginInfrastructure;
[13347]26using Google.ProtocolBuffers;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
[13326]28
29namespace HeuristicLab.Persistence {
[13347]30  public sealed class Mapper {
[13358]31    private static StaticCache staticCache = null;
32    private static object locker = new object();
33    public static StaticCache StaticCache {
34      get {
35        lock (locker) {
36          if (staticCache == null) staticCache = new StaticCache();
37          return staticCache;
38        }
39      }
40    }
41
[13347]42    private Index<ITransformer> transformers;
43    private Index<Type> types;
[13326]44    private Index<string> strings;
[13347]45    private Index<Box> boxes;
[13358]46    private Dictionary<object, uint> object2BoxId;
47    private Dictionary<uint, object> boxId2object;
[13326]48
[13347]49    public long BoxCount { get; private set; }
[13326]50
[13347]51    public Mapper() {
52      transformers = new Index<ITransformer>();
53      types = new Index<Type>();
[13326]54      strings = new Index<string>();
[13347]55      boxes = new Index<Box>();
[13358]56      object2BoxId = new Dictionary<object, uint>(new ReferenceEqualityComparer<object>());
57      boxId2object = new Dictionary<uint, object>();
[13326]58
[13347]59      BoxCount = 0;
[13326]60    }
61
[13358]62    public uint GetTransformerId(ITransformer transformer) {
63      return transformers.GetIndex(transformer);
[13326]64    }
[13358]65    public ITransformer GetTransformer(uint transformerId) {
66      return transformers.GetValue(transformerId);
[13326]67    }
68
[13347]69    public uint GetTypeId(Type type) {
[13326]70      return types.GetIndex(type);
71    }
[13347]72    public Type GetType(uint typeId) {
[13326]73      return types.GetValue(typeId);
74    }
75
76    public uint GetStringId(string str) {
77      return strings.GetIndex(str);
78    }
79    public string GetString(uint stringId) {
80      return strings.GetValue(stringId);
81    }
82
[13347]83    public uint GetBoxId(object o) {
84      uint boxId;
[13358]85      if (object2BoxId.TryGetValue(o, out boxId)) return boxId;
[13347]86
87      if (o == null)
88        boxId = boxes.GetIndex(null);
89      else {
90        var type = o.GetType();
[13358]91        var typeInfo = StaticCache.GetTypeInfo(type);
[13347]92        if (typeInfo.Transformer == null) throw new ArgumentException("Cannot serialize object of type " + o.GetType());
93        BoxCount++;
94        typeInfo.Used++;
95        boxId = boxes.GetIndex(typeInfo.Transformer.ToBox(o, this));
96      }
[13358]97      object2BoxId.Add(o, boxId);
[13347]98      return boxId;
[13326]99    }
[13347]100    public object GetObject(uint boxId) {
101      object o;
[13358]102      if (boxId2object.TryGetValue(boxId, out o)) return o;
[13326]103
[13347]104      var box = this.boxes.GetValue(boxId);
105      if (box == null)
106        o = null;
107      else {
108        var transformer = transformers.GetValue(box.TransformerId);
109        o = transformer.ToObject(box, this);
110      }
[13358]111      boxId2object.Add(boxId, o);
[13347]112      return o;
[13326]113    }
114
115    public object CreateInstance(Type type) {
[13358]116      return StaticCache.GetTypeInfo(type).GetConstructor()();
[13326]117    }
118
[13347]119    public static Bundle ToBundle(object o) {
120      var mapper = new Mapper();
121      var bundle = Bundle.CreateBuilder();
122      bundle.RootBoxId = mapper.GetBoxId(o);
123      bundle.AddRangeTransformerGuids(mapper.transformers.GetValues().Select(x => x.Guid).Select(x => ByteString.CopyFrom(x.ToByteArray())));
[13358]124      bundle.AddRangeTypeGuids(mapper.types.GetValues().Select(x => StaticCache.GetGuid(x)).Select(x => ByteString.CopyFrom(x.ToByteArray())));
[13347]125      bundle.AddRangeStrings(mapper.strings.GetValues());
126      bundle.AddRangeBoxes(mapper.boxes.GetValues());
127      return bundle.Build();
[13326]128    }
[13347]129    public static object ToObject(Bundle bundle) {
130      var mapper = new Mapper();
[13358]131      mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => new Guid(x.ToByteArray())).Select(x => StaticCache.GetType(x)));
[13347]132      mapper.strings = new Index<string>(bundle.StringsList);
133      mapper.boxes = new Index<Box>(bundle.BoxesList);
[13358]134      mapper.transformers = new Index<ITransformer>(bundle.TransformerGuidsList.Select(x => new Guid(x.ToByteArray())).Select(x => StaticCache.GetTransformer(x)));
[13347]135      return mapper.GetObject(bundle.RootBoxId);
[13326]136    }
137  }
138}
Note: See TracBrowser for help on using the repository browser.