public bool AddItem(BaseSnapshotItem obj, int id) { if (obj == null) { Debug.Warning("snapshots", "add null object"); return(false); } if (SnapshotItems.Count + 1 >= MaxItems) { Debug.Warning("snapshots", "too many items"); return(false); } var itemSize = SnapshotItemsInfo.GetSize(obj.GetType()); if (SnapshotSize + itemSize >= Snapshot.MaxSize) { Debug.Warning("snapshots", "too much data"); return(false); } var item = new SnapshotItem(id, obj); SnapshotSize += itemSize; SnapshotItems.Add(item); return(true); }
public int[] ToArray() { var array = new int[SnapshotItemsInfo.GetSize(GetType()) / sizeof(int)]; var handle = GCHandle.Alloc(array, GCHandleType.Pinned); var ptr = handle.AddrOfPinnedObject(); Marshal.StructureToPtr(this, ptr, false); handle.Free(); return(array); }
public T NewItem <T>(int id) where T : BaseSnapshotItem, new() { if (SnapshotItems.Count + 1 >= MaxItems) { Debug.Warning("snapshots", "too many items"); return(null); } var itemSize = SnapshotItemsInfo.GetSize <T>(); if (SnapshotSize + itemSize >= Snapshot.MaxSize) { Debug.Warning("snapshots", "too much data"); return(null); } var item = new SnapshotItem(id, new T()); SnapshotSize += itemSize; SnapshotItems.Add(item); return((T)item.Item); }
public static int CreateDelta(Snapshot from, Snapshot to, int[] outputData) { var numDeletedItems = 0; var numUpdatedItems = 0; var numTempItems = 0; var outputOffset = 3; var hashItems = new HashItem[HASHLIST_SIZE]; for (var i = 0; i < hashItems.Length; i++) { hashItems[i] = new HashItem(); } GenerateHash(hashItems, to); for (var i = 0; i < from.ItemsCount; i++) { var fromItem = from[i]; if (GetItemIndexHashed(fromItem.Key, hashItems) == -1) { numDeletedItems++; outputData[outputOffset++] = fromItem.Key; } } GenerateHash(hashItems, from); var pastIndecies = new int[SnapshotBuilder.MaxItems]; // fetch previous indices // we do this as a separate pass because it helps the cache for (var i = 0; i < to.ItemsCount; i++) { pastIndecies[i] = GetItemIndexHashed(to[i].Key, hashItems); } for (var i = 0; i < to.ItemsCount; i++) { var currentItem = to[i]; var itemSize = SnapshotItemsInfo.GetSize(currentItem.Item.GetType()); var pastIndex = pastIndecies[i]; if (pastIndex != -1) { var pastItem = from[pastIndex]; var offset = outputOffset + 3; if (itemSize != 0) { offset = outputOffset + 2; } if (DiffItem(pastItem.Item, currentItem.Item, outputData, offset) != 0) { outputData[outputOffset++] = (int)currentItem.Item.Type; outputData[outputOffset++] = currentItem.Id; if (itemSize == 0) { outputData[outputOffset++] = itemSize / sizeof(int); } outputOffset += itemSize / sizeof(int); // count item int fields numUpdatedItems++; } } else { outputData[outputOffset++] = (int)currentItem.Item.Type; outputData[outputOffset++] = currentItem.Id; if (itemSize == 0) { outputData[outputOffset++] = itemSize / sizeof(int); } var data = currentItem.Item.ToArray(); var output = outputData.AsSpan(outputOffset, data.Length); data.CopyTo(output); outputOffset += data.Length; numUpdatedItems++; } } if (numDeletedItems == 0 && numUpdatedItems == 0 && numTempItems == 0) { return(0); } outputData[0] = numDeletedItems; outputData[1] = numUpdatedItems; outputData[2] = numTempItems; return(outputOffset); }