Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }