Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/20/17 11:16:42 (7 years ago)
Author:
jkarder
Message:

#2520: worked on persistence

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs

    r14549 r14594  
    807807    }
    808808    public override Box ToBox(object o, Mapper mapper) {
    809       Array arr = (Array)o;
    810       if (arr.GetLowerBound(0) != 0 || arr.Rank > 1) throw new NotSupportedException();
    811 
    812809      var box = Box.CreateBuilder();
    813810      box.TransformerId = mapper.GetTransformerId(this);
     
    816813    }
    817814    private void Populate(Box.Builder box, object value, Mapper mapper) {
     815      var type = value.GetType();
    818816      var array = (Array)value;
    819       var elementType = value.GetType().GetElementType();
     817      var rank = array.Rank;
    820818
    821819      var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
    822       foreach (var item in (IEnumerable)array)
    823         uIntArrayBox.AddValues(mapper.GetBoxId(item));
    824 
    825       box.TypeId = mapper.GetBoxId(elementType);
     820      uIntArrayBox.AddValues(mapper.GetBoxId(rank));
     821
     822      int[] lengths = new int[rank];
     823      int[] lowerBounds = new int[rank];
     824      for (int i = 0; i < rank; i++) {
     825        lengths[i] = array.GetLength(i);
     826        lowerBounds[i] = array.GetLowerBound(i);
     827      }
     828
     829      uIntArrayBox.AddRangeValues(lengths.Select(x => mapper.GetBoxId(x)));
     830      uIntArrayBox.AddRangeValues(lowerBounds.Select(x => mapper.GetBoxId(x)));
     831
     832      int[] positions = (int[])lowerBounds.Clone();
     833      while (positions[rank - 1] < lengths[rank - 1] + lowerBounds[rank - 1]) {
     834        uIntArrayBox.AddValues(mapper.GetBoxId(array.GetValue(positions)));
     835        positions[0] += 1;
     836        for (int i = 0; i < rank - 1; i++) {
     837          if (positions[i] >= lowerBounds[i] + lengths[i]) {
     838            positions[i] = lowerBounds[i];
     839            positions[i + 1] += 1;
     840          } else {
     841            break;
     842          }
     843        }
     844      }
     845
     846      box.TypeId = mapper.GetBoxId(type);
    826847      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
    827848    }
    828849    public override object ToObject(Box box, Mapper mapper) {
    829850      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
     851      var rank = (int)mapper.GetObject(uIntArrayBox.GetValues(0));
     852
     853      int[] lengths = new int[rank], lowerBounds = new int[rank];
     854      for (int i = 0; i < rank; i++)
     855        lengths[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1));
     856      for (int i = 0; i < rank; i++)
     857        lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1 + rank));
     858
    830859      var type = (Type)mapper.GetObject(box.TypeId);
    831       return Array.CreateInstance(type, uIntArrayBox.ValuesCount);
     860      return Array.CreateInstance(type.GetElementType(), lengths, lowerBounds);
    832861    }
    833862    public override void FillFromBox(object obj, Box box, Mapper mapper) {
     863      var array = (Array)obj;
    834864      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    835       Array.Copy(uIntArrayBox.ValuesList.Select(x => mapper.GetObject(x)).ToArray(), (Array)obj, uIntArrayBox.ValuesCount);
     865      var rank = (int)mapper.GetObject(uIntArrayBox.GetValues(0));
     866
     867      int[] lengths = new int[rank], lowerBounds = new int[rank];
     868      for (int i = 0; i < rank; i++)
     869        lengths[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1));
     870      for (int i = 0; i < rank; i++)
     871        lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1 + rank));
     872
     873      int[] positions = (int[])lowerBounds.Clone();
     874      var e = uIntArrayBox.ValuesList.Skip(1 + 2 * rank).GetEnumerator();
     875      while (e.MoveNext()) {
     876        int[] currentPositions = positions;
     877        array.SetValue(mapper.GetObject(e.Current), currentPositions);
     878        positions[0] += 1;
     879        for (int i = 0; i < rank - 1; i++) {
     880          if (positions[i] >= lengths[i] + lowerBounds[i]) {
     881            positions[i] = lowerBounds[i];
     882            positions[i + 1] += 1;
     883          } else {
     884            break;
     885          }
     886        }
     887      }
    836888    }
    837889  }
     
    857909    private void Populate(Box.Builder box, object value, Mapper mapper) {
    858910      var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
     911
     912      var type = value.GetType();
     913      var propertyInfo = type.GetProperty("Comparer");
     914      if (propertyInfo != null) {
     915        // TODO: where to store id for comparer box? (atm: first element in int array ...)
     916        var comparer = propertyInfo.GetValue(value);
     917        var comparerType = comparer.GetType();
     918        if (Default.CompositeSerializers.Storable.StorableClassAttribute.IsStorableClass(comparerType))
     919          uIntArrayBox.AddValues(mapper.GetBoxId(comparer));
     920        else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
     921          throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
     922        else
     923          uIntArrayBox.AddValues(mapper.GetBoxId(comparerType));
     924      }
     925
    859926      foreach (var item in (IEnumerable)value)
    860927        uIntArrayBox.AddValues(mapper.GetBoxId(item));
    861       box.TypeId = mapper.GetBoxId(value.GetType());
     928
     929      box.TypeId = mapper.GetBoxId(type);
    862930      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
    863931    }
     
    865933      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    866934      var type = (Type)mapper.GetObject(box.TypeId);
    867       return Activator.CreateInstance(type, uIntArrayBox.ValuesCount);
     935      return Activator.CreateInstance(type);
    868936    }
    869937    public override void FillFromBox(object obj, Box box, Mapper mapper) {
     
    871939      var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject);
    872940      var type = obj.GetType();
     941
    873942      string methodName = string.Empty;
    874943      if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Stack<>) || type == typeof(Stack)) {
     
    879948      } else {
    880949        methodName = "Add";
     950        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) {
     951          var fieldInfo = type.GetField("m_comparer", BindingFlags.NonPublic | BindingFlags.Instance);
     952          var comparerObj = mapper.GetObject(uIntArrayBox.GetValues(0));
     953          var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
     954          fieldInfo.SetValue(obj, comparer);
     955          elements = elements.Skip(1);
     956        }
    881957      }
    882958
     
    909985      var comparer = propertyInfo.GetValue(value);
    910986
    911       dictionaryBox.SetComparerId(mapper.GetBoxId(comparer));
    912       box.TypeId = mapper.GetBoxId(value.GetType());
     987      var comparerType = comparer.GetType();
     988      if (Default.CompositeSerializers.Storable.StorableClassAttribute.IsStorableClass(comparerType))
     989        dictionaryBox.SetComparerId(mapper.GetBoxId(comparer));
     990      else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
     991        throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
     992      else
     993        dictionaryBox.SetComparerId(mapper.GetBoxId(comparerType));
     994
     995      box.TypeId = mapper.GetBoxId(type);
    913996      box.SetExtension(DictionaryBox.Dictionary, dictionaryBox.Build());
    914997    }
     
    9201003      var type = obj.GetType();
    9211004      var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary);
    922       var comparer = mapper.GetObject(dictionaryBox.ComparerId);
     1005      var comparerObj = mapper.GetObject(dictionaryBox.ComparerId);
     1006      var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
     1007
     1008      var fieldInfo = type.GetField("comparer", BindingFlags.NonPublic | BindingFlags.Instance);
     1009      fieldInfo.SetValue(obj, comparer);
     1010
     1011
    9231012      var addMethod = type.GetMethod("Add");
    9241013      for (int i = 0; i < dictionaryBox.KeyIdsCount; i++) {
Note: See TracChangeset for help on using the changeset viewer.