예제 #1
0
        /// <summary>
        /// Allocate a new counter with a given label.
        ///
        /// The key function will be called with a buffer with the exact length of available key space
        /// in the record for the user to store what they want for the key. No offset is required.
        /// </summary>
        /// <param name="label">   to describe the counter. </param>
        /// <param name="typeId">  for the type of counter. </param>
        /// <param name="keyFunc"> for setting the key value for the counter. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(string label, int typeId, Action <IMutableDirectBuffer> keyFunc)
        {
            var counterId = NextCounterId();

            CheckCountersCapacity(counterId);

            var recordOffset = MetaDataOffset(counterId);

            CheckMetaDataCapacity(recordOffset);

            try
            {
                MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);
                keyFunc(new UnsafeBuffer(MetaDataBuffer, recordOffset + KEY_OFFSET, MAX_KEY_LENGTH));
                MetaDataBuffer.PutLong(recordOffset + FREE_FOR_REUSE_DEADLINE_OFFSET, NOT_FREE_TO_REUSE);
                PutLabel(recordOffset, label);

                MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);
            }
            catch (Exception)
            {
                _freeList.Add(counterId);
                throw;
            }

            return(counterId);
        }
예제 #2
0
        /// <summary>
        /// Allocate a new counter with a given label.
        ///
        /// The key function will be called with a buffer with the exact length of available key space
        /// in the record for the user to store what they want for the key. No offset is required.
        /// </summary>
        /// <param name="label">   to describe the counter. </param>
        /// <param name="typeId">  for the type of counter. </param>
        /// <param name="keyFunc"> for setting the key value for the counter. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(string label, int typeId, Action <IMutableDirectBuffer> keyFunc)
        {
            var counterId = NextCounterId();

            if (CounterOffset(counterId) + COUNTER_LENGTH > ValuesBuffer.Capacity)
            {
                throw new InvalidOperationException("Unable to allocated counter, values buffer is full");
            }

            var recordOffset = MetaDataOffset(counterId);

            if (recordOffset + METADATA_LENGTH > MetaDataBuffer.Capacity)
            {
                throw new InvalidOperationException("Unable to allocate counter, labels buffer is full");
            }


            try
            {
                MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);
                keyFunc(new UnsafeBuffer(MetaDataBuffer, recordOffset + KEY_OFFSET, MAX_KEY_LENGTH));
                PutLabel(recordOffset, label);

                MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);
            }
            catch (Exception)
            {
                _freeList.Enqueue(counterId);
                throw;
            }

            return(counterId);
        }
예제 #3
0
        /// <summary>
        /// Allocate a new counter with a given label and type.
        /// </summary>
        /// <param name="label">  to describe the counter. </param>
        /// <param name="typeId"> for the type of counter. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(string label, int typeId = DEFAULT_TYPE_ID)
        {
            int counterId = NextCounterId();

            CheckCountersCapacity(counterId);

            int recordOffset = MetaDataOffset(counterId);

            CheckMetaDataCapacity(recordOffset);

            try
            {
                MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);
                MetaDataBuffer.PutLong(recordOffset + FREE_FOR_REUSE_DEADLINE_OFFSET, NOT_FREE_TO_REUSE);
                PutLabel(recordOffset, label);
                MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);
            }
            catch (Exception)
            {
                _freeList.Add(counterId);
                throw;
            }

            return(counterId);
        }
예제 #4
0
        /// <summary>
        /// Allocate a new counter with a given label and type.
        /// </summary>
        /// <param name="label">  to describe the counter. </param>
        /// <param name="typeId"> for the type of counter. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(string label, int typeId = DEFAULT_TYPE_ID)
        {
            int counterId = NextCounterId();

            if ((CounterOffset(counterId) + COUNTER_LENGTH) > ValuesBuffer.Capacity)
            {
                throw new InvalidOperationException("Unable to allocated counter, values buffer is full");
            }

            int recordOffset = MetaDataOffset(counterId);

            if ((recordOffset + METADATA_LENGTH) > MetaDataBuffer.Capacity)
            {
                throw new InvalidOperationException("Unable to allocate counter, labels buffer is full");
            }

            try
            {
                MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);
                PutLabel(recordOffset, label);
                MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);
            }
            catch (Exception)
            {
                _freeList.Enqueue(counterId);
                throw;
            }

            return(counterId);
        }
예제 #5
0
        private void PutLabel(int recordOffset, string label)
        {
            if (Encoding.ASCII.Equals(LabelCharset))
            {
                int length = MetaDataBuffer.PutStringWithoutLengthAscii(recordOffset + LABEL_OFFSET + BitUtil.SIZE_OF_INT, label, 0, MAX_LABEL_LENGTH);
                MetaDataBuffer.PutInt(recordOffset + LABEL_OFFSET, length);
            }
            else
            {
                byte[] bytes  = LabelCharset.GetBytes(label);
                int    length = Math.Min(bytes.Length, MAX_LABEL_LENGTH);

                MetaDataBuffer.PutInt(recordOffset + LABEL_OFFSET, length);
                MetaDataBuffer.PutBytes(recordOffset + LABEL_OFFSET + BitUtil.SIZE_OF_INT, bytes, 0, length);
            }
        }
예제 #6
0
        /// <summary>
        /// Allocate a counter with the minimum of allocation by allowing the label an key to be provided and copied.
        /// <para>
        /// If the keyBuffer is null then a copy of the key is not attempted.
        ///
        /// </para>
        /// </summary>
        /// <param name="typeId">      for the counter. </param>
        /// <param name="keyBuffer">   containing the optional key for the counter. </param>
        /// <param name="keyOffset">   within the keyBuffer at which the key begins. </param>
        /// <param name="keyLength">   of the key in the keyBuffer. </param>
        /// <param name="labelBuffer"> containing the mandatory label for the counter. </param>
        /// <param name="labelOffset"> within the labelBuffer at which the label begins. </param>
        /// <param name="labelLength"> of the label in the labelBuffer. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(int typeId, IDirectBuffer keyBuffer, int keyOffset, int keyLength, IDirectBuffer labelBuffer, int labelOffset, int labelLength)
        {
            int counterId = NextCounterId();

            if ((CounterOffset(counterId) + COUNTER_LENGTH) > ValuesBuffer.Capacity)
            {
                throw new InvalidOperationException("Unable to allocated counter, values buffer is full");
            }

            int recordOffset = MetaDataOffset(counterId);

            if ((recordOffset + METADATA_LENGTH) > MetaDataBuffer.Capacity)
            {
                throw new InvalidOperationException("Unable to allocate counter, labels buffer is full");
            }

            try
            {
                MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);

                int length;

                if (null != keyBuffer)
                {
                    length = Math.Min(keyLength, MAX_KEY_LENGTH);
                    MetaDataBuffer.PutBytes(recordOffset + KEY_OFFSET, keyBuffer, keyOffset, length);
                }

                length = Math.Min(labelLength, MAX_LABEL_LENGTH);
                MetaDataBuffer.PutInt(recordOffset + LABEL_OFFSET, length);
                MetaDataBuffer.PutBytes(recordOffset + LABEL_OFFSET + BitUtil.SIZE_OF_INT, labelBuffer, labelOffset, length);

                MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);
            }
            catch (Exception)
            {
                _freeList.Enqueue(counterId);
                throw;
            }

            return(counterId);
        }
예제 #7
0
        private void PutLabel(int recordOffset, string label)
        {
            if (Encoding.ASCII.Equals(LabelCharset))
            {
                MetaDataBuffer.PutStringAscii(recordOffset + LABEL_OFFSET, label.Length > MAX_LABEL_LENGTH ? label.Substring(0, MAX_LABEL_LENGTH) : label);
            }
            else
            {
                byte[] bytes = LabelCharset.GetBytes(label);

                if (bytes.Length > MAX_LABEL_LENGTH)
                {
                    MetaDataBuffer.PutInt(recordOffset + LABEL_OFFSET, MAX_LABEL_LENGTH);
                    MetaDataBuffer.PutBytes(recordOffset + LABEL_OFFSET + BitUtil.SIZE_OF_INT, bytes, 0, MAX_LABEL_LENGTH);
                }
                else
                {
                    MetaDataBuffer.PutInt(recordOffset + LABEL_OFFSET, bytes.Length);
                    MetaDataBuffer.PutBytes(recordOffset + LABEL_OFFSET + BitUtil.SIZE_OF_INT, bytes);
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Allocate a new counter with a given label.
        /// </summary>
        /// <param name="label"> to describe the counter. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(string label)
        {
            int counterId = NextCounterId();

            if ((CounterOffset(counterId) + COUNTER_LENGTH) > ValuesBuffer.Capacity)
            {
                throw new ArgumentException("Unable to allocated counter, values buffer is full");
            }

            int recordOffset = MetaDataOffset(counterId);

            if ((recordOffset + METADATA_LENGTH) > MetaDataBuffer.Capacity)
            {
                throw new ArgumentException("Unable to allocate counter, labels buffer is full");
            }

            MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, DEFAULT_TYPE_ID);
            MetaDataBuffer.PutStringUtf8(recordOffset + LABEL_OFFSET, label, MAX_LABEL_LENGTH);

            MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);

            return(counterId);
        }
예제 #9
0
        /// <summary>
        /// Allocate a counter with the minimum of allocation by allowing the label an key to be provided and copied.
        /// <para>
        /// If the keyBuffer is null then a copy of the key is not attempted.
        ///
        /// </para>
        /// </summary>
        /// <param name="typeId">      for the counter. </param>
        /// <param name="keyBuffer">   containing the optional key for the counter. </param>
        /// <param name="keyOffset">   within the keyBuffer at which the key begins. </param>
        /// <param name="keyLength">   of the key in the keyBuffer. </param>
        /// <param name="labelBuffer"> containing the mandatory label for the counter. </param>
        /// <param name="labelOffset"> within the labelBuffer at which the label begins. </param>
        /// <param name="labelLength"> of the label in the labelBuffer. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(int typeId, IDirectBuffer keyBuffer, int keyOffset, int keyLength, IDirectBuffer labelBuffer, int labelOffset, int labelLength)
        {
            int counterId = NextCounterId();

            CheckCountersCapacity(counterId);

            int recordOffset = MetaDataOffset(counterId);

            CheckMetaDataCapacity(recordOffset);

            try
            {
                MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);
                MetaDataBuffer.PutLong(recordOffset + FREE_FOR_REUSE_DEADLINE_OFFSET, NOT_FREE_TO_REUSE);

                int length;

                if (null != keyBuffer)
                {
                    length = Math.Min(keyLength, MAX_KEY_LENGTH);
                    MetaDataBuffer.PutBytes(recordOffset + KEY_OFFSET, keyBuffer, keyOffset, length);
                }

                length = Math.Min(labelLength, MAX_LABEL_LENGTH);
                MetaDataBuffer.PutInt(recordOffset + LABEL_OFFSET, length);
                MetaDataBuffer.PutBytes(recordOffset + LABEL_OFFSET + BitUtil.SIZE_OF_INT, labelBuffer, labelOffset, length);

                MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);
            }
            catch (Exception)
            {
                _freeList.Add(counterId);
                throw;
            }

            return(counterId);
        }
예제 #10
0
        /// <summary>
        /// Allocate a new counter with a given label.
        ///
        /// The key function will be called with a buffer with the exact length of available key space
        /// in the record for the user to store what they want for the key. No offset is required.
        /// </summary>
        /// <param name="label">   to describe the counter. </param>
        /// <param name="typeId">  for the type of counter. </param>
        /// <param name="keyFunc"> for setting the key value for the counter. </param>
        /// <returns> the id allocated for the counter. </returns>
        public int Allocate(string label, int typeId, Action <IMutableDirectBuffer> keyFunc)
        {
            var counterId = NextCounterId();

            if (CounterOffset(counterId) + COUNTER_LENGTH > ValuesBuffer.Capacity)
            {
                throw new ArgumentException("Unable to allocated counter, values buffer is full");
            }

            var recordOffset = MetaDataOffset(counterId);

            if (recordOffset + METADATA_LENGTH > MetaDataBuffer.Capacity)
            {
                throw new ArgumentException("Unable to allocate counter, labels buffer is full");
            }

            MetaDataBuffer.PutInt(recordOffset + TYPE_ID_OFFSET, typeId);
            keyFunc(new UnsafeBuffer(MetaDataBuffer, recordOffset + KEY_OFFSET, MAX_KEY_LENGTH));
            MetaDataBuffer.PutStringUtf8(recordOffset + LABEL_OFFSET, label, MAX_LABEL_LENGTH);

            MetaDataBuffer.PutIntOrdered(recordOffset, RECORD_ALLOCATED);

            return(counterId);
        }