Exemple #1
0
        private unsafe long CalculateSize(IEventPayloads payloads)
        {
            // event count + crc
            // foreach event: meta + payload

            long size = sizeof(byte) + sizeof(uint);

            foreach (var e in payloads)
            {
                size += sizeof(EventMeta);
                size += e.Count;
            }

            return(size);
        }
Exemple #2
0
        public unsafe Task <IEnumerable <EventMeta> > Write(IEventPayloads payload)
        {
            lock (_view) {
                // early out if we are complete
                if (_isComplete)
                {
                    return(null);
                }

                // early out if we don't have enough space left in the log
                var space = _view.Capacity - _position;
                if (space < CalculateSize(payload))
                {
                    return(null);
                }

                var events = new List <EventMeta>();

                try {
                    byte *ptr = null;
                    _view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);

                    var start = _position;

                    // write event count in the batch
                    *(ptr + _position) = (byte)payload.Count;
                    _position         += sizeof(byte);

                    foreach (var e in payload)
                    {
                        // write event meta block
                        var meta = new EventMeta {
                            Created = DateTime.UtcNow,
                            Id      = _start + _count
                        };

                        *(EventMeta *)(ptr + _position) = meta;
                        _position += sizeof(EventMeta);

                        // write event payload
                        *(ushort *)(ptr + _position) = (ushort)e.Count;
                        _position += sizeof(ushort);

                        Marshal.Copy(e.Array, e.Offset, (IntPtr)(ptr + _position), e.Count);
                        _position += e.Count;

                        // increment event count
                        _count++;
                        events.Add(meta);
                    }

                    // post-fix batch with crc
                    var length    = (int)(_position - start);
                    var crcBuffer = GetBuffer(length);
                    Marshal.Copy((IntPtr)(ptr + start), crcBuffer, 0, length);
                    var crc = Crc32Algorithm.Compute(crcBuffer, 0, length);

                    *(uint *)(ptr + _position) = crc;
                    _position += sizeof(uint);
                }
                finally {
                    _view.SafeMemoryMappedViewHandle.ReleasePointer();
                }

                // store a handle to the task - to be completed when the buffer is flushed
                var tcs = new TaskCompletionSource <IEnumerable <EventMeta> >();
                _awaiting.Add(() => tcs.SetResult(events));

                return(tcs.Task);
            }
        }
Exemple #3
0
 public Task <IEnumerable <EventMeta> > Store(IEventPayloads payload) => throw new NotImplementedException();