DotNetty.Buffers Abstract base class implementation of a Abstract base class for instances Abstract base class for implementations that wrap another . Returns a hex dump of the specified buffer's sub-region. Returns a hex dump of the specified buffer's sub-region. Returns a hex dump of the specified buffer's sub-region. Returns a hex dump of the specified buffer's sub-region. Calculates the hash code of the specified buffer. This method is useful when implementing a new buffer type. Returns the reader index of needle in haystack, or -1 if needle is not in haystack. Returns {@code true} if and only if the two specified buffers are identical to each other for {@code length} bytes starting at {@code aStartIndex} index for the {@code a} buffer and {@code bStartIndex} index for the {@code b} buffer. A more compact way to express this is:

{@code a[aStartIndex : aStartIndex + length] == b[bStartIndex : bStartIndex + length]}

Returns {@code true} if and only if the two specified buffers are identical to each other as described in {@link ByteBuf#equals(Object)}. This method is useful when implementing a new buffer type. Compares the two specified buffers as described in {@link ByteBuf#compareTo(ByteBuf)}. This method is useful when implementing a new buffer type. The default implementation of . This method is useful when implementing a new buffer type. Read the given amount of bytes into a new {@link ByteBuf} that is allocated from the {@link ByteBufAllocator}. Encode a string in http://en.wikipedia.org/wiki/UTF-8 and write it into reserveBytes of a byte buffer. The reserveBytes must be computed (ie eagerly using {@link #utf8MaxBytes(string)} or exactly with #utf8Bytes(string)}) to ensure this method not to not: for performance reasons the index checks will be performed using just reserveBytes. This method returns the actual number of bytes written. Encode the given using the given into a new which is allocated via the . The to allocate {@link IByteBuffer}. src The to encode. charset The specified Encode the given using the given into a new which is allocated via the . The to allocate {@link IByteBuffer}. src The to encode. charset The specified the extra capacity to alloc except the space for decoding. Returns a multi-line hexadecimal dump of the specified {@link ByteBuf} that is easy to read by humans. Returns a multi-line hexadecimal dump of the specified {@link ByteBuf} that is easy to read by humans, starting at the given {@code offset} using the given {@code length}. Appends the prettified multi-line hexadecimal dump of the specified {@link ByteBuf} to the specified {@link StringBuilder} that is easy to read by humans. Appends the prettified multi-line hexadecimal dump of the specified {@link ByteBuf} to the specified {@link StringBuilder} that is easy to read by humans, starting at the given {@code offset} using the given {@code length}. Toggles the endianness of the specified 64-bit long integer. Toggles the endianness of the specified 32-bit integer. Toggles the endianness of the specified 16-bit integer. Default on most Windows systems Add the given {@link IByteBuffer}. Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuffer}. If you need to have it increased you need to handle it by your own. @param buffer the {@link IByteBuffer} to add Add the given {@link IByteBuffer}s. Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuffer}. If you need to have it increased you need to handle it by your own. @param buffers the {@link IByteBuffer}s to add Add the given {@link IByteBuffer}s. Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuffer}. If you need to have it increased you need to handle it by your own. @param buffers the {@link IByteBuffer}s to add Add the given {@link IByteBuffer} on the specific index. Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuffer}. If you need to have it increased you need to handle it by your own. @param cIndex the index on which the {@link IByteBuffer} will be added @param buffer the {@link IByteBuffer} to add Add the given {@link IByteBuffer}s on the specific index Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuffer}. If you need to have it increased you need to handle it by your own. @param cIndex the index on which the {@link IByteBuffer} will be added. @param buffers the {@link IByteBuffer}s to add Add the given {@link ByteBuf}s on the specific index Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuffer}. If you need to have it increased you need to handle it by your own. @param cIndex the index on which the {@link IByteBuffer} will be added. @param buffers the {@link IByteBuffer}s to add This should only be called as last operation from a method as this may adjust the underlying array of components and so affect the index etc. Remove the {@link IByteBuffer} from the given index. @param cIndex the index on from which the {@link IByteBuffer} will be remove Remove the number of {@link IByteBuffer}s starting from the given index. @param cIndex the index on which the {@link IByteBuffer}s will be started to removed @param numComponents the number of components to remove Same with {@link #slice(int, int)} except that this method returns a list. Return the current number of {@link IByteBuffer}'s that are composed in this instance Return the max number of {@link IByteBuffer}'s that are composed in this instance Return the index for the given offset Return the {@link IByteBuffer} on the specified index @param cIndex the index for which the {@link IByteBuffer} should be returned @return buffer the {@link IByteBuffer} on the specified index Return the {@link IByteBuffer} on the specified index @param offset the offset for which the {@link IByteBuffer} should be returned @return the {@link IByteBuffer} on the specified index Return the internal {@link IByteBuffer} on the specified index. Note that updating the indexes of the returned buffer will lead to an undefined behavior of this buffer. @param cIndex the index for which the {@link IByteBuffer} should be returned Return the internal {@link IByteBuffer} on the specified offset. Note that updating the indexes of the returned buffer will lead to an undefined behavior of this buffer. @param offset the offset for which the {@link IByteBuffer} should be returned Consolidate the composed {@link IByteBuffer}s Consolidate the composed {@link IByteBuffer}s @param cIndex the index on which to start to compose @param numComponents the number of components to compose Discard all {@link IByteBuffer}s which are read. Represents an empty byte buffer Inspired by the Netty ByteBuffer implementation (https://github.com/netty/netty/blob/master/buffer/src/main/java/io/netty/buffer/ByteBuf.java) Provides circular-buffer-esque security around a byte array, allowing reads and writes to occur independently. In general, the guarantees: /// LESS THAN OR EQUAL TO LESS THAN OR EQUAL TO . Expands the capacity of this buffer so long as it is less than . The allocator who created this buffer Sets the of this buffer thrown if exceeds the length of the buffer Sets the of this buffer thrown if is greater than or less than 0. Sets both indexes thrown if or exceeds the length of the buffer Returns true if - is greater than 0. Is the buffer readable if and only if the buffer contains equal or more than the specified number of elements The number of elements we would like to read Returns true if and only if - is greater than zero. Returns true if and only if the buffer has enough to accomodate additional bytes. The number of additional elements we would like to write. Sets the and to 0. Does not erase any of the data written into the buffer already, but it will overwrite that data. Marks the current in this buffer. You can reposition the current to the marked by calling . The initial value of the marked is 0. Repositions the current to the marked in this buffer. is thrown if the current is less than the marked Marks the current in this buffer. You can reposition the current to the marked by calling . The initial value of the marked is 0. Repositions the current to the marked in this buffer. is thrown if the current is greater than the marked Discards the bytes between the 0th index and . It moves the bytes between and to the 0th index, and sets and to 0 and oldWriterIndex - oldReaderIndex respectively. Similar to except that this method might discard some, all, or none of read bytes depending on its internal implementation to reduce overall memory bandwidth consumption at the cost of potentially additional memory consumption. Makes sure the number of is equal to or greater than the specified value (.) If there is enough writable bytes in this buffer, the method returns with no side effect. Otherwise, it raises an . The expected number of minimum writable bytes if + > . Tries to make sure the number of is equal to or greater than the specified value. Unlike , this method does not raise an exception but returns a code. the expected minimum number of writable bytes When + minWritableBytes > :
  • true - the capacity of the buffer is expanded to
  • false - the capacity of the buffer is unchanged
0 if the buffer has enough writable bytes, and its capacity is unchanged. 1 if the buffer does not have enough bytes, and its capacity is unchanged. 2 if the buffer has enough writable bytes, and its capacity has been increased. 3 if the buffer does not have enough bytes, but its capacity has been increased to its maximum.
Gets a boolean at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 1 greater than Gets a byte at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 1 greater than Gets a short at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 2 greater than Gets a short at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 2 greater than Gets an ushort at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 2 greater than Gets an ushort at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 2 greater than Gets an integer at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 4 greater than Gets an integer at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 4 greater than Gets an unsigned integer at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 4 greater than Gets an unsigned integer at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 4 greater than Gets a long integer at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 8 greater than Gets a long integer at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 8 greater than Gets a 24-bit medium integer at the specified absolute index in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 3 greater than Gets a 24-bit medium integer at the specified absolute index in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 3 greater than Gets an unsigned 24-bit medium integer at the specified absolute index in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 3 greater than Gets an unsigned 24-bit medium integer at the specified absolute index in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 3 greater than Gets a char at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 2 greater than Gets a float at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 4 greater than Gets a float at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 4 greater than Gets a double at the specified absolute in this buffer. This method does not modify or of this buffer. if the specified is less than 0 or index + 8 greater than Gets a double at the specified absolute in this buffer in Little Endian Byte Order. This method does not modify or of this buffer. if the specified is less than 0 or index + 8 greater than Transfers this buffers data to the specified buffer starting at the specified absolute until the destination becomes non-writable. if the specified is less than 0 or index + 1 greater than Transfers this buffers data to the specified buffer starting at the specified absolute until the destination becomes non-writable. if the specified is less than 0 or index + 1 greater than Transfers this buffers data to the specified buffer starting at the specified absolute until the destination becomes non-writable. if the specified is less than 0 or index + 1 greater than Transfers this buffers data to the specified buffer starting at the specified absolute until the destination becomes non-writable. if the specified is less than 0 or index + 1 greater than Transfers this buffers data to the specified buffer starting at the specified absolute until the destination becomes non-writable. if the specified is less than 0 or index + 1 greater than Transfers this buffer's data to the specified stream starting at the specified absolute index. This method does not modify readerIndex or writerIndex of this buffer. absolute index in this buffer to start getting bytes from destination stream the number of bytes to transfer if the specified index is less than 0 or if index + length is greater than this.capacity Gets a string with the given length at the given index. length the length to read charset that should be use the string value. if length is greater than readable bytes. Sets the specified boolean at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 1 greater than Sets the specified byte at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 1 greater than Sets the specified short at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 2 greater than Sets the specified short at the specified absolute in this buffer in the Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 2 greater than Sets the specified unsigned short at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 2 greater than Sets the specified unsigned short at the specified absolute in this buffer in the Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 2 greater than Sets the specified integer at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Sets the specified integer at the specified absolute in this buffer in the Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Sets the specified unsigned integer at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Sets the specified unsigned integer at the specified absolute in this buffer in the Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Sets the specified 24-bit medium integer at the specified absolute in this buffer. Note that the most significant byte is ignored in the specified value. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 3 greater than Sets the specified 24-bit medium integer at the specified absolute in this buffer. Note that the most significant byte is ignored in the specified value. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 3 greater than Sets the specified long integer at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 8 greater than Sets the specified long integer at the specified absolute in this buffer in the Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 8 greater than Sets the specified UTF-16 char at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 2 greater than Sets the specified double at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 8 greater than Sets the specified float at the specified absolute in this buffer. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Sets the specified float at the specified absolute in this buffer in Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Sets the specified float at the specified absolute in this buffer in Little Endian Byte Order. This method does not directly modify or of this buffer. if the specified is less than 0 or index + 4 greater than Transfers the byte buffer's contents starting at the specified absolute . This method does not directly modify or of this buffer. if the specified is less than 0 or + .ReadableBytes greater than Transfers the byte buffer's contents starting at the specified absolute . This method does not directly modify or of this buffer. if the specified is less than 0 or is less than 0 or + greater than Transfers the byte buffer's contents starting at the specified absolute . This method does not directly modify or of this buffer. if the specified is less than 0 or is less than 0 or is less than 0 or + greater than or + greater than .Capacity Transfers the byte buffer's contents starting at the specified absolute . This method does not directly modify or of this buffer. if the specified is less than 0 or + .Length greater than Transfers the byte buffer's contents starting at the specified absolute . This method does not directly modify or of this buffer. if the specified is less than 0 or is less than 0 or is less than 0 or + greater than or + greater than .Length Transfers the content of the specified source stream to this buffer starting at the specified absolute . This method does not modify or of this buffer. absolute index in this byte buffer to start writing to number of bytes to transfer cancellation token the actual number of bytes read in from the specified channel. if the specified index is less than 0 or if index + length is greater than this.capacity Fills this buffer with NULL (0x00) starting at the specified absolute index. This method does not modify reader index or writer index of this buffer absolute index in this byte buffer to start writing to length the number of NULs to write to the buffer if the specified index is less than 0 or if index + length is greater than capacity. Writes the specified string at the current writer index and increases the writer index by the written bytes. Index on which the string should be written The string value. Encoding that should be used. The written number of bytes. if writable bytes is not large enough to write the whole string. Gets a boolean at the current and increases the by 1 in this buffer. if is less than 1 Gets a byte at the current and increases the by 1 in this buffer. if is less than 1 Gets a short at the current and increases the by 2 in this buffer. if is less than 2 Gets a short at the current in the Little Endian Byte Order and increases the by 2 in this buffer. if is less than 2 Gets a 24-bit medium integer at the current and increases the by 3 in this buffer. if is less than 3 Gets a 24-bit medium integer at the current in the Little Endian Byte Order and increases the by 3 in this buffer. if is less than 3 Gets an unsigned 24-bit medium integer at the current and increases the by 3 in this buffer. if is less than 3 Gets an unsigned 24-bit medium integer at the current in the Little Endian Byte Order and increases the by 3 in this buffer. if is less than 3 Gets an unsigned short at the current and increases the by 2 in this buffer. if is less than 2 Gets an unsigned short at the current in the Little Endian Byte Order and increases the by 2 in this buffer. if is less than 2 Gets an integer at the current and increases the by 4 in this buffer. if is less than 4 Gets an integer at the current in the Little Endian Byte Order and increases the by 4 in this buffer. if is less than 4 Gets an unsigned integer at the current and increases the by 4 in this buffer. if is less than 4 Gets an unsigned integer at the current in the Little Endian Byte Order and increases the by 4 in this buffer. if is less than 4 Gets an long at the current and increases the by 8 in this buffer. if is less than 4 Gets an long at the current in the Little Endian Byte Order and increases the by 8 in this buffer. if is less than 4 Gets a 2-byte UTF-16 character at the current and increases the by 2 in this buffer. if is less than 2 Gets an 8-byte Decimaling integer at the current and increases the by 8 in this buffer. if is less than 8 Gets an 8-byte Decimaling integer at the current and increases the by 8 in this buffer in Little Endian Byte Order. if is less than 8 Gets an 4-byte Decimaling integer at the current and increases the by 4 in this buffer. if is less than 4 Gets an 4-byte Decimaling integer at the current and increases the by 4 in this buffer in Little Endian Byte Order. if is less than 4 Reads bytes from this buffer into a new destination buffer. if is less than Transfers bytes from this buffer's data into the specified destination buffer starting at the curent until the destination becomes non-writable and increases the by the number of transferred bytes. if destination. is greater than . Gets a string with the given length at the current reader index and increases the reader index by the given length. The length to read Encoding that should be used The string value Increases the current by the specified in this buffer. if is greater than . Returns the maximum of that this buffer holds. Note that or might return a less number of s of . -1 if this buffer cannot represent its content as of . the number of the underlying s if this buffer has at least one underlying segment. Note that this method does not return 0 to avoid confusion. Exposes this buffer's readable bytes as an of . Returned segment shares the content with this buffer. This method is identical to buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes). This method does not modify or of this buffer. Please note that the returned segment will not see the changes of this buffer if this buffer is a dynamic buffer and it adjusted its capacity. if this buffer cannot represent its content as of Exposes this buffer's sub-region as an of . Returned segment shares the content with this buffer. This method does not modify or of this buffer. Please note that the returned segment will not see the changes of this buffer if this buffer is a dynamic buffer and it adjusted its capacity. if this buffer cannot represent its content as of Exposes this buffer's readable bytes as an array of of . Returned segments share the content with this buffer. This method does not modify or of this buffer. Please note that returned segments will not see the changes of this buffer if this buffer is a dynamic buffer and it adjusted its capacity. if this buffer cannot represent its content with of Exposes this buffer's bytes as an array of of for the specified index and length. Returned segments share the content with this buffer. This method does not modify or of this buffer. Please note that returned segments will not see the changes of this buffer if this buffer is a dynamic buffer and it adjusted its capacity. if this buffer cannot represent its content with of Flag that indicates if this is backed by a byte array or not Grabs the underlying byte array for this buffer Returns {@code true} if and only if this buffer has a reference to the low-level memory address that points to the backing data. Returns the low-level memory address that point to the first byte of ths backing data. The low-level memory address Returns the pointer address of the buffer if the memory is pinned. IntPtr.Zero if not pinned. Creates a deep clone of the existing byte array and returns it Unwraps a nested buffer Returns a copy of this buffer's readable bytes. Modifying the content of the returned buffer or this buffer does not affect each other at all.This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}. This method does not modify {@code readerIndex} or {@code writerIndex} of this buffer. Iterates over the readable bytes of this buffer with the specified processor in ascending order. -1 if the processor iterated to or beyond the end of the readable bytes. The last-visited index If the returned false. Processor. Iterates over the specified area of this buffer with the specified in ascending order. (i.e. , (index + 1), .. (index + length - 1)) -1 if the processor iterated to or beyond the end of the specified area. The last-visited index If the returned false. Index. Length. Processor. Iterates over the readable bytes of this buffer with the specified in descending order. -1 if the processor iterated to or beyond the beginning of the readable bytes. The last-visited index If the returned false. Processor. Iterates over the specified area of this buffer with the specified in descending order. (i.e. (index + length - 1), (index + length - 2), ... ) -1 if the processor iterated to or beyond the beginning of the specified area. The last-visited index If the returned false. Index. Length. Processor. Thread-safe interface for allocating /. Returns the number of bytes of heap memory used by a {@link ByteBufAllocator} or {@code -1} if unknown. Returns the number of bytes of direct memory used by a {@link ByteBufAllocator} or {@code -1} if unknown. Returns a for a Return the data which is held by this {@link ByteBufHolder}. Create a deep copy of this {@link ByteBufHolder}. Duplicate the {@link ByteBufHolder}. Be aware that this will not automatically call {@link #retain()}. Duplicates this {@link ByteBufHolder}. This method returns a retained duplicate unlike {@link #duplicate()}. Returns a new {@link ByteBufHolder} which contains the specified {@code content}. Returns the number of thread caches backed by this arena. Returns the number of tiny sub-pages for the arena. Returns the number of small sub-pages for the arena. Returns the number of chunk lists for the arena. Returns an unmodifiable {@link List} which holds {@link PoolSubpageMetric}s for tiny sub-pages. Returns an unmodifiable {@link List} which holds {@link PoolSubpageMetric}s for small sub-pages. Returns an unmodifiable {@link List} which holds {@link PoolChunkListMetric}s. Return the number of allocations done via the arena. This includes all sizes. Return the number of tiny allocations done via the arena. Return the number of small allocations done via the arena. Return the number of normal allocations done via the arena. Return the number of huge allocations done via the arena. Return the number of deallocations done via the arena. This includes all sizes. Return the number of tiny deallocations done via the arena. Return the number of small deallocations done via the arena. Return the number of normal deallocations done via the arena. Return the number of huge deallocations done via the arena. Return the number of currently active allocations. Return the number of currently active tiny allocations. Return the number of currently active small allocations. Return the number of currently active normal allocations. Return the number of currently active huge allocations. Return the number of active bytes that are currently allocated by the arena. Return the minum usage of the chunk list before which chunks are promoted to the previous list. Return the minum usage of the chunk list after which chunks are promoted to the next list. Return the percentage of the current usage of the chunk. Return the size of the chunk in bytes, this is the maximum of bytes that can be served out of the chunk. Return the number of free bytes in the chunk. Return the number of maximal elements that can be allocated out of the sub-page. Return the number of available elements to be allocated. Return the size (in bytes) of the elements that will be allocated. Return the size (in bytes) of this page. Description of algorithm for PageRun/PoolSubpage allocation from PoolChunk Notation: The following terms are important to understand the code > page - a page is the smallest unit of memory chunk that can be allocated > chunk - a chunk is a collection of pages > in this code chunkSize = 2^{maxOrder} /// pageSize To begin we allocate a byte array of size = chunkSize Whenever a ByteBuf of given size needs to be created we search for the first position in the byte array that has enough empty space to accommodate the requested size and return a (long) handle that encodes this offset information, (this memory segment is then marked as reserved so it is always used by exactly one ByteBuf and no more) For simplicity all sizes are normalized according to PoolArena#normalizeCapacity method This ensures that when we request for memory segments of size >= pageSize the normalizedCapacity equals the next nearest power of 2 To search for the first offset in chunk that has at least requested size available we construct a complete balanced binary tree and store it in an array (just like heaps) - memoryMap The tree looks like this (the size of each node being mentioned in the parenthesis) depth=0 1 node (chunkSize) depth=1 2 nodes (chunkSize/2) .. .. depth=d 2^d nodes (chunkSize/2^d) .. depth=maxOrder 2^maxOrder nodes (chunkSize/2^{maxOrder} = pageSize) depth=maxOrder is the last level and the leafs consist of pages With this tree available searching in chunkArray translates like this: To allocate a memory segment of size chunkSize/2^k we search for the first node (from left) at height k which is unused Algorithm: ---------- Encode the tree in memoryMap with the notation memoryMap[id] = x => in the subtree rooted at id, the first node that is free to be allocated is at depth x (counted from depth=0) i.e., at depths [depth_of_id, x), there is no node that is free As we allocate and free nodes, we update values stored in memoryMap so that the property is maintained Initialization - In the beginning we construct the memoryMap array by storing the depth of a node at each node i.e., memoryMap[id] = depth_of_id Observations: ------------- 1) memoryMap[id] = depth_of_id => it is free / unallocated 2) memoryMap[id] > depth_of_id => at least one of its child nodes is allocated, so we cannot allocate it, but some of its children can still be allocated based on their availability 3) memoryMap[id] = maxOrder + 1 => the node is fully allocated and thus none of its children can be allocated, it is thus marked as unusable Algorithm: [allocateNode(d) => we want to find the first node (from left) at height h that can be allocated] ---------- 1) start at root (i.e., depth = 0 or id = 1) 2) if memoryMap[1] > d => cannot be allocated from this chunk 3) if left node value <= h; we can allocate from left subtree so move to left and repeat until found 4) else try in right subtree Algorithm: [allocateRun(size)] ---------- 1) Compute d = log_2(chunkSize/size) 2) Return allocateNode(d) Algorithm: [allocateSubpage(size)] ---------- 1) use allocateNode(maxOrder) to find an empty (i.e., unused) leaf (i.e., page) 2) use this handle to construct the PoolSubpage object or if it already exists just call init(normCapacity) note that this PoolSubpage object is added to subpagesPool in the PoolArena when we init() it Note: ----- In the implementation for improving cache coherence, we store 2 pieces of information (i.e, 2 byte vals) as a short value in memoryMap memoryMap[id]= (depth_of_id, x) where as per convention defined above the second value (i.e, x) indicates that the first node which is free to be allocated is at depth x (from root) Used to determine if the requested capacity is equal to or greater than pageSize. Used to mark memory as unusable Creates a special chunk that is not pooled. Update method used by allocate This is triggered only when a successor is allocated and all its predecessors need to update their state The minimal depth at which subtree rooted at id has some free space @param id id Update method used by free This needs to handle the special case when both children are completely free in which case parent be directly allocated on request of size = child-size * 2 @param id id Algorithm to allocate an index in memoryMap when we query for a free node at depth d @param d depth @return index in memoryMap Allocate a run of pages (>=1) @param normCapacity normalized capacity @return index in memoryMap Create/ initialize a new PoolSubpage of normCapacity Any PoolSubpage created/ initialized here is added to subpage pool in the PoolArena that owns this PoolChunk @param normCapacity normalized capacity @return index in memoryMap Free a subpage or a run of pages When a subpage is freed from PoolSubpage, it might be added back to subpage pool of the owning PoolArena If the subpage pool in PoolArena has at least one other PoolSubpage of given elemSize, we can completely free the owning Page so it is available for subsequent allocations @param handle handle to free represents the size in #bytes supported by node 'id' in the tree Calculates the maximum capacity of a buffer that will ever be possible to allocate out of the {@link PoolChunk}s that belong to the {@link PoolChunkList} with the given {@code minUsage} and {@code maxUsage} settings. Moves the {@link PoolChunk} down the {@link PoolChunkList} linked-list so it will end up in the right {@link PoolChunkList} that has the correct minUsage / maxUsage in respect to {@link PoolChunk#usage()}. Adds the {@link PoolChunk} to this {@link PoolChunkList}. Method must be called before reuse this {@link PooledByteBufAllocator} Returns the status of the allocator (which contains all metrics) as string. Be aware this may be expensive and so should not called too frequently. Special constructor that creates a linked list head Returns the bitmap index of the subpage allocation. @return {@code true} if this subpage is in use. {@code false} if this subpage is not used by its chunk and thus it's OK to be released. Acts a Thread cache for allocations. This implementation is moduled after jemalloc and the descripted technics of Scalable memory allocation using jemalloc . Try to allocate a tiny buffer out of the cache. Returns {@code true} if successful {@code false} otherwise Try to allocate a small buffer out of the cache. Returns {@code true} if successful {@code false} otherwise Try to allocate a small buffer out of the cache. Returns {@code true} if successful {@code false} otherwise Add {@link PoolChunk} and {@code handle} to the cache if there is enough room. Returns {@code true} if it fit into the cache {@code false} otherwise. Should be called if the Thread that uses this cache is about to exist to release resources out of the cache Cache used for buffers which are backed by TINY or SMALL size. Cache used for buffers which are backed by NORMAL size. Init the {@link PooledByteBuffer} using the provided chunk and handle with the capacity restrictions. Add to cache if not already full. Allocate something out of the cache if possible and remove the entry from the cache. Clear out this cache and free up all previous cached {@link PoolChunk}s and {@code handle}s. Free up cached {@link PoolChunk}s if not allocated frequently enough. Utility class for managing and creating unpooled buffers Creates a new big-endian buffer which wraps the specified array. A modification on the specified array's content will be visible to the returned buffer. Creates a new big-endian buffer which wraps the sub-region of the specified array. A modification on the specified array's content will be visible to the returned buffer. Creates a new buffer which wraps the specified buffer's readable bytes. A modification on the specified buffer's content will be visible to the returned buffer. The buffer to wrap. Reference count ownership of this variable is transfered to this method. The readable portion of the buffer, or an empty buffer if there is no readable portion. Creates a new big-endian composite buffer which wraps the specified arrays without copying them. A modification on the specified arrays' content will be visible to the returned buffer. Creates a new big-endian composite buffer which wraps the readable bytes of the specified buffers without copying them. A modification on the content of the specified buffers will be visible to the returned buffer. The buffers to wrap. Reference count ownership of all variables is transfered to this method. The readable portion of the buffers. The caller is responsible for releasing this buffer. Creates a new big-endian composite buffer which wraps the specified arrays without copying them. A modification on the specified arrays' content will be visible to the returned buffer. Creates a new big-endian composite buffer which wraps the readable bytes of the specified buffers without copying them. A modification on the content of the specified buffers will be visible to the returned buffer. Advisement as to how many independent buffers are allowed to exist before consolidation occurs. The buffers to wrap. Reference count ownership of all variables is transfered to this method. The readable portion of the buffers. The caller is responsible for releasing this buffer. Creates a new big-endian buffer whose content is a copy of the specified array The new buffer's and are 0 and respectively. A buffer we're going to copy. The new buffer that copies the contents of array. Creates a new big-endian buffer whose content is a copy of the specified array. The new buffer's and are 0 and respectively. A buffer we're going to copy. The index offset from which we're going to read array. The number of bytes we're going to read from array beginning from position offset. The new buffer that copies the contents of array. Creates a new big-endian buffer whose content is a copy of the specified . The new buffer's and are 0 and respectively. A buffer we're going to copy. The new buffer that copies the contents of buffer. Creates a new big-endian buffer whose content is a merged copy of of the specified arrays. The new buffer's and are 0 and respectively. Creates a new big-endian buffer whose content is a merged copy of the specified . The new buffer's and are 0 and respectively. Buffers we're going to copy. The new buffer that copies the contents of buffers. Creates a new 4-byte big-endian buffer that holds the specified 32-bit integer. Create a big-endian buffer that holds a sequence of the specified 32-bit integers. Creates a new 2-byte big-endian buffer that holds the specified 16-bit integer. Create a new big-endian buffer that holds a sequence of the specified 16-bit integers. Create a new big-endian buffer that holds a sequence of the specified 16-bit integers. Creates a new 3-byte big-endian buffer that holds the specified 24-bit integer. Create a new big-endian buffer that holds a sequence of the specified 24-bit integers. Creates a new 8-byte big-endian buffer that holds the specified 64-bit integer. Create a new big-endian buffer that holds a sequence of the specified 64-bit integers. Creates a new single-byte big-endian buffer that holds the specified boolean value. Create a new big-endian buffer that holds a sequence of the specified boolean values. Creates a new 4-byte big-endian buffer that holds the specified 32-bit floating point number. Create a new big-endian buffer that holds a sequence of the specified 32-bit floating point numbers. Creates a new 8-byte big-endian buffer that holds the specified 64-bit floating point number. Create a new big-endian buffer that holds a sequence of the specified 64-bit floating point numbers. Return a unreleasable view on the given {@link ByteBuf} which will just ignore release and retain calls. Unpooled implementation of . Wraps another . It's important that the {@link #readerIndex()} and {@link #writerIndex()} will not do any adjustments on the indices on the fly because of internal optimizations made by {@link ByteBufUtil#writeAscii(ByteBuf, CharSequence)} and {@link ByteBufUtil#writeUtf8(ByteBuf, CharSequence)}.