/// <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); }
/// <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); }
/// <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); }
/// <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); }
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); } }
/// <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); }
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); } } }
/// <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); }
/// <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); }
/// <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); }