Beispiel #1
0
        protected virtual unsafe void OnLogAppend(DirectBuffer buffer)
        {
            var writerPid     = buffer.ReadInt64(DataHeaderFlyweight.RESERVED_VALUE_OFFSET);
            var messageBuffer = new DirectBuffer(buffer.Length - DataHeaderFlyweight.HEADER_LENGTH,
                                                 buffer.Data + DataHeaderFlyweight.HEADER_LENGTH);
            var header = *(CommandHeader *)(messageBuffer.Data);
            var uuid   = header.SeriesId;

            IAcceptCommand series;

            if (
                writerPid != Pid                          // ignore our own messages
                &&
                _openSeries.TryGetValue(uuid, out series) // ignore messages for closed series
                )
            {
                if (header.CommandType == CommandType.Broadcast)
                {
                    OnBroadcast?.Invoke(messageBuffer);
                }
                else
                {
                    series.ApplyCommand(messageBuffer);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Deletes up to (but not including) this value for the key.
        /// </summary>
        /// <param name="tx">transaction</param>
        /// <param name="db">database</param>
        /// <param name="key">key</param>
        /// <param name="value">Value (or part of the value) to which the data will be deleted</param>
        /// <param name="firstValue">First value to position to the beginning of dupes. Even if first value is bigger it is OK.</param>
        /// <returns></returns>
        public static unsafe bool DeleteUpToValue(this Transaction tx, Database db, long key, long value, long firstValue = 0L)
        {
            int deletedCount = 0;

            using (var c = db.OpenCursor(tx))
            {
                try
                {
                    byte *keyptr      = (byte *)Unsafe.AsPointer(ref key);
                    byte *valptr      = (byte *)Unsafe.AsPointer(ref value);
                    byte *firstvalptr = (byte *)Unsafe.AsPointer(ref firstValue);
                    var   keydb       = new DirectBuffer(sizeof(long), keyptr);
                    var   valdb       = new DirectBuffer(sizeof(long), firstvalptr);
                    c.TryFindDup(Lookup.LE, ref keydb, ref valdb);

                    while (c.Delete(false))
                    {
                        deletedCount++;
                        if (!c.TryGet(ref keydb, ref valdb, CursorGetOption.GetBothRange) || valdb.IsEmpty)
                        {
                            break; // empty now
                        }
                        var currentValue = valdb.ReadInt64(0);
                        if (currentValue == value)
                        {
                            break;
                        }
                    }

                    return(true);
                }
                catch (Exception e)
                {
                    throw new DeleteUpToException(
                              $"Failed after deleting {deletedCount} records."
                              , e);
                }
            }
        }
Beispiel #3
0
 /**
  * Get the value of the correlation ID for this log.
  *
  * @param logMetaDataBuffer containing the meta data.
  * @return the value of the correlation ID used for this log.
  */
 public static long CorrelationId(DirectBuffer logMetaDataBuffer)
 {
     return(logMetaDataBuffer.ReadInt64(LOG_CORRELATION_ID_OFFSET));
 }
Beispiel #4
0
        protected unsafe void OnLogAppend(DirectBuffer buffer)
        {
            var writerPid     = buffer.ReadInt64(DataHeaderFlyweight.RESERVED_VALUE_OFFSET);
            var messageBuffer = new DirectBuffer(buffer.Length - DataHeaderFlyweight.HEADER_LENGTH,
                                                 buffer.Data + DataHeaderFlyweight.HEADER_LENGTH);
            var header      = *(MessageHeader *)(messageBuffer.Data);
            var seriesId    = header.UUID;
            var messageType = header.MessageType;

            switch (messageType)
            {
            case MessageType.ConductorMessage:
                // this message could be sent only by a process that
                // thinks it is a conductor
                var currentConductor = writerPid;
                if (Math.Abs(currentConductor) != Pid)
                {
                    // negative writerPid must be sent on conductor repo dispose
                    _isConductor = writerPid <= 0 && TryBecomeConductor();
                }
                break;

            case MessageType.WriteRequest:
                if (_isConductor)
                {
                    BeginAcquireWriteLock(seriesId, writerPid);
                }
                break;

            case MessageType.CurrentWriter:
                // new writer is sent by a conductor in response
                TaskCompletionSource <long> temp;
                if (_writerRequestsOustanding.TryGetValue(seriesId, out temp))
                {
                    temp.SetResult(writerPid);
                }
                break;

            case MessageType.Subscribe:
                if (_isConductor)
                {
                    IAcceptCommand tempAcceptCommand;
                    if (_openStreams.TryGetValue(seriesId, out tempAcceptCommand))
                    {
                        tempAcceptCommand.Flush();
                    }
                    BeginSyncronizeSeries(seriesId, header.Version);
                }
                break;

            case MessageType.Synced:
                TaskCompletionSource <byte> temp2;
                if (_syncRequestsOustanding.TryGetValue(seriesId, out temp2))
                {
                    temp2.SetResult(1);
                }
                break;


            default:
                IAcceptCommand acceptCommand;
                if (writerPid != Pid &&  // ignore our own messages
                    _openStreams.TryGetValue(seriesId, out acceptCommand)        // ignore messages for closed series
                    )
                {
                    acceptCommand.ApplyCommand(messageBuffer);
                }
                break;
            }
        }