ByteBuf

5.1 ByteBuf API

ByteBuf๋Š” Netty์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ปจํ…Œ์ด๋„ˆ๋กœ, JDK์˜ ByteBuffer์— ๋น„ํ•ด ๋งŽ์€ ์ด์ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ByteBuf๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๋ฉ”์„œ๋“œ๋กœ๋Š” ์ฝ๊ธฐ, ์“ฐ๊ธฐ, ๊ฒ€์ƒ‰ ๋“ฑ์ด ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ByteBuf๋Š” ํˆฌ๋ช…ํ•œ ์ œ๋กœ-์นดํ”ผ์™€ ์šฉ๋Ÿ‰ ํ™•์žฅ์„ฑ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ, ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

5.2 Class ByteBuf

๋ชจ๋“  ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์€ ๋ฐ”์ดํŠธ ์‹œํ€€์Šค์˜ ์ด๋™์„ ํฌํ•จํ•˜๋ฏ€๋กœ ํšจ์œจ์ ์ด๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Netty์˜ ByteBuf ๊ตฌํ˜„์€ ์ด๋Ÿฌํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑ์‹œํ‚ต๋‹ˆ๋‹ค.

ByteBuf๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด readerIndex์™€ writerIndex๋ผ๋Š” ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ์ธ๋ฑ์Šค๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ๋งˆ๋‹ค readerIndex๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ๋•Œ๋งˆ๋‹ค writerIndex๊ฐ€ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

5.2.1 ์ž‘๋™ ๋ฐฉ์‹

ByteBuf๋Š” ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ๋ฅผ ์œ„ํ•œ ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ์ธ๋ฑ์Šค๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ByteBuf์—์„œ ์ฝ์„ ๋•Œ๋งˆ๋‹ค readerIndex๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ณ , ์“ธ ๋•Œ๋งˆ๋‹ค writerIndex๊ฐ€ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, readerIndex๊ฐ€ writerIndex์— ๋„๋‹ฌํ•˜๋ฉด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ๋์— ๋„๋‹ฌํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
while (buffer.isReadable()) {
    System.out.println(buffer.readByte());
}

5.2.2 ByteBuf ์‚ฌ์šฉ ํŒจํ„ด

Netty๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ByteBuf ์‚ฌ์šฉ ํŒจํ„ด์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํž™ ๋ฒ„ํผ

ํž™ ๊ณต๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ€์žฅ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ByteBuf ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์€ ํ’€๋ง์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์—์„œ ๋น ๋ฅธ ํ• ๋‹น๊ณผ ํ•ด์ œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ByteBuf heapBuf = ...;
if (heapBuf.hasArray()) {                    
    byte[] array = heapBuf.array();                            
    int offset = heapBuf.arrayOffset() + heapBuf.readerIndex();  
    int length = heapBuf.readableBytes();           
    handleArray(array, offset, length);   
}

์ง์ ‘ ๋ฒ„ํผ

์ง์ ‘ ๋ฒ„ํผ๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ํ˜ธ์ถœ์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ๋ฐ์ดํ„ฐ ์ „์†ก์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค. ์ง์ ‘ ๋ฒ„ํผ์˜ ์ฃผ์š” ๋‹จ์ ์€ ํž™ ๊ธฐ๋ฐ˜ ๋ฒ„ํผ๋ณด๋‹ค ํ• ๋‹น ๋ฐ ํ•ด์ œ ๋น„์šฉ์ด ๋” ๋งŽ์ด ๋“ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ByteBuf directBuf = ...;
if (!directBuf.hasArray()) {              
    int length = directBuf.readableBytes();               
    byte[] array = new byte[length];                              
    directBuf.getBytes(directBuf.readerIndex(), array);  
    handleArray(array, 0, length);        
}

์ปดํฌ์ง€ํŠธ ๋ฒ„ํผ

์ปดํฌ์ง€ํŠธ ๋ฒ„ํผ๋Š” ์—ฌ๋Ÿฌ ByteBuf์˜ ์ง‘ํ•ฉ์  ๋ทฐ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ํ•„์š”์— ๋”ฐ๋ผ ByteBuf ์ธ์Šคํ„ด์Šค๋ฅผ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CompositeByteBuf๋Š” ์—ฌ๋Ÿฌ ByteBuf๋ฅผ ํ•˜๋‚˜๋กœ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‹จ์ผ ๋ฒ„ํผ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ถ„์‚ฐ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹จ์ผ ByteBuf๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

CompositeByteBuf๋Š” ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. CompositeByteBuf์˜ ์ฃผ์š” ๋ฉ”์„œ๋“œ๋กœ๋Š” addComponent(), removeComponent(), numComponents() ๋“ฑ์ด ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฒ„ํผ๋ฅผ ๋™์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CompositeByteBuf compBuf = Unpooled.compositeBuffer();
ByteBuf headerBuf = ...;
ByteBuf bodyBuf = ...;
compBuf.addComponents(headerBuf, bodyBuf);

CompositeByteBuf์˜ ๋˜ ๋‹ค๋ฅธ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์€ ์Šฌ๋ผ์ด์Šค(slices)๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šฌ๋ผ์ด์Šค๋Š” ์›๋ž˜ ๋ฒ„ํผ์˜ ์ผ๋ถ€๋ถ„์„ ์ฐธ์กฐํ•˜๋Š” ByteBuf ์ธ์Šคํ„ด์Šค๋กœ, ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ ์—†์ด๋„ ์›๋ž˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

CompositeByteBuf compBuf = Unpooled.compositeBuffer();
ByteBuf headerBuf = ...;
ByteBuf bodyBuf = ...;
compBuf.addComponents(true, headerBuf, bodyBuf);

ByteBuf slice = compBuf.slice(0, headerBuf.readableBytes());

ByteBuf

5.3 Byte-level operations

ByteBuf๋Š” ๊ธฐ๋ณธ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ์ž‘์—… ์™ธ์—๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

5.3.1 Domain access indexing

ByteBuf๋Š” ํŠน์ • ์˜์—ญ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ๋ถ€๋ถ„ ์˜์—ญ์— ๋Œ€ํ•ด ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

getBytes(int index, byte[] dst, int dstIndex, int length)์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
byte[] dst = new byte[buffer.readableBytes()];
buffer.getBytes(buffer.readerIndex(), dst, 0, dst.length);

5.3.2 Sequential (Linear) access indexing

ByteBuf๋Š” readerIndex์™€ writerIndex๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. readByte()์™€ writeByte(byte value) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
while (buffer.isReadable()) {
    System.out.println(buffer.readByte());
}
buffer.writeByte((byte) 'a');

5.3.3 Discardable bytes

ByteBuf๋Š” ์ฝ๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ๋ฐ”์ดํŠธ๋ฅผ ๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. discardReadBytes() ๋ฉ”์„œ๋“œ๋Š” readerIndex ์ด์ „์˜ ๋ฐ”์ดํŠธ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
buffer.readBytes(new byte[buffer.readableBytes()]);
buffer.discardReadBytes();

5.3.4 Readable bytes

ByteBuf์˜ ์ฝ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ฐ”์ดํŠธ ์˜์—ญ์€ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

์ƒˆ๋กœ ํ• ๋‹น๋œ, ๋ž˜ํ•‘๋œ, ๋˜๋Š” ๋ณต์‚ฌ๋œ ๋ฒ„ํผ์˜ ๊ธฐ๋ณธ readerIndex ๊ฐ’์€ 0์ž…๋‹ˆ๋‹ค. ์ด๋ฆ„์ด read ๋˜๋Š” skip์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ํ˜„์žฌ readerIndex์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ๊ฑด๋„ˆ๋›ฐ๊ณ , ์ฝ์€ ๋ฐ”์ดํŠธ ์ˆ˜๋งŒํผ readerIndex๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ByteBuf ์ธ์ˆ˜๋ฅผ ์“ฐ๊ธฐ ๋Œ€์ƒ(buffer)์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ , ๋Œ€์ƒ ์ธ๋ฑ์Šค ์ธ์ˆ˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, ๋Œ€์ƒ ๋ฒ„ํผ์˜ writerIndex๋„ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

readBytes(ByteBuf dest);

์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ดํŠธ๊ฐ€ ์†Œ์ง„๋œ ์ƒํƒœ์—์„œ ๋ฒ„ํผ์—์„œ ์ฝ์œผ๋ ค ํ•˜๋ฉด, IndexOutOfBoundsException์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
while (buffer.isReadable()) {
    System.out.println(buffer.readByte());
}

5.3.5 Writable bytes

ByteBuf์˜ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ฐ”์ดํŠธ ์˜์—ญ์€ ์ •์˜๋˜์ง€ ์•Š์€ ๋‚ด์šฉ์˜ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์œผ๋กœ, ์“ฐ๊ธฐ ์ž‘์—…์„ ์œ„ํ•ด ์ค€๋น„๋œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

์ƒˆ๋กœ ํ• ๋‹น๋œ ๋ฒ„ํผ์˜ ๊ธฐ๋ณธ writerIndex ๊ฐ’์€ 0์ž…๋‹ˆ๋‹ค. ์ด๋ฆ„์ด write๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ํ˜„์žฌ writerIndex์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๊ธฐ ์‹œ์ž‘ํ•˜๊ณ , ์“ด ๋ฐ”์ดํŠธ ์ˆ˜๋งŒํผ writerIndex๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์“ฐ๊ธฐ ์ž‘์—…์˜ ๋Œ€์ƒ์ด ByteBuf์ด๊ณ , ์†Œ์Šค ์ธ๋ฑ์Šค๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์†Œ์Šค ๋ฒ„ํผ์˜ readerIndex๋„ ๋™์ผํ•œ ์–‘๋งŒํผ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋žœ๋ค ์ •์ˆ˜ ๊ฐ’์œผ๋กœ ๋ฒ„ํผ์˜ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ฐ”์ดํŠธ๋ฅผ ์ฑ„์šฐ๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
while (buffer.writableBytes() >= 4) {
    buffer.writeInt(random.nextInt());
}

5.3.6 Index management

JDK์˜ InputStream์€ ํ˜„์žฌ ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ํ•ด๋‹น ์œ„์น˜๋กœ ์ŠคํŠธ๋ฆผ์„ ์žฌ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด mark(int readlimit) ๋ฐ reset() ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

์ด์™€ ์œ ์‚ฌํ•˜๊ฒŒ ByteBuf์—์„œ๋„ markReaderIndex(), markWriterIndex(), resetReaderIndex(), resetWriterIndex() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ readerIndex์™€ writerIndex๋ฅผ ์„ค์ •ํ•˜๊ณ  ์žฌ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ๋“ค์€ InputStream์˜ ํ˜ธ์ถœ๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ, ํ‘œ์‹œ๊ฐ€ ๋ฌดํšจํ™”๋˜๋Š” ์‹œ์ ์„ ์ง€์ •ํ•˜๋Š” readlimit ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ readerIndex(int) ๋˜๋Š” writerIndex(int) ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ๋ฑ์Šค๋ฅผ ์ง€์ •๋œ ์œ„์น˜๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ์œ ํšจํ•˜์ง€ ์•Š์€ ์œ„์น˜๋กœ ์„ค์ •ํ•˜๋ ค๊ณ  ํ•˜๋ฉด IndexOutOfBoundsException์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

clear() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ readerIndex์™€ writerIndex๋ฅผ ๋ชจ๋‘ 0์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์šฉ์„ ์ง€์šฐ์ง€๋Š” ์•Š์ง€๋งŒ ์ธ๋ฑ์Šค๋ฅผ ์žฌ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. clear() ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ  ์ธ๋ฑ์Šค๋ฅผ ์žฌ์„ค์ •ํ•˜๋ฏ€๋กœ discardReadBytes()๋ณด๋‹ค ํ›จ์”ฌ ์ €๋ ดํ•ฉ๋‹ˆ๋‹ค.

5.3.7 Search operations

ByteBuf์—์„œ ์ง€์ •๋œ ๊ฐ’์˜ ์ธ๋ฑ์Šค๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ indexOf() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋” ๋ณต์žกํ•œ ๊ฒ€์ƒ‰์€ ByteBufProcessor ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ boolean process(byte value)๋ฅผ ์ •์˜ํ•˜๋ฉฐ, ์ž…๋ ฅ ๊ฐ’์ด ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ’์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ๋Š” ์บ๋ฆฌ์ง€ ๋ฆฌํ„ด ๋ฌธ์ž(\r)๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ByteBufProcessor๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ByteBuf buffer = ...;
int index = buffer.forEachByte(ByteBufProcessor.FIND_CR);

5.3.8 Derived buffers

ํŒŒ์ƒ ๋ฒ„ํผ๋Š” ByteBuf์˜ ๋‚ด์šฉ์„ ํŠน์ˆ˜ํ•œ ๋ฐฉ์‹์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋Š” ๋ทฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ทฐ๋Š” ๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์„ ํ†ตํ•ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค:

  • duplicate()

  • slice()

  • slice(int, int)

  • Unpooled.unmodifiableBuffer(...)

  • order(ByteOrder)

  • readSlice(int)

๊ฐ ๋ฉ”์„œ๋“œ๋Š” ์ž์ฒด reader, writer ๋ฐ ๋งˆ์ปค ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์ง„ ์ƒˆ๋กœ์šด ByteBuf ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ €์žฅ์†Œ๋Š” JDK ByteBuffer์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ณต์œ ๋ฉ๋‹ˆ๋‹ค.

์ด๋Š” ํŒŒ์ƒ ๋ฒ„ํผ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋น„์šฉ์ด ์ €๋ ดํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ, ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•˜๋ฉด ์›๋ณธ ์ธ์Šคํ„ด์Šค๋„ ์ˆ˜์ •๋œ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ๋Š” slice(int, int)์„ ์‚ฌ์šฉํ•˜์—ฌ ByteBuf ์„ธ๊ทธ๋จผํŠธ๋ฅผ ์ž‘์—…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
ByteBuf sliced = buf.slice(0, 14);
System.out.println(sliced.toString(utf8));
buf.setByte(0, (byte)'J');
assert buf.getByte(0) == sliced.getByte(0);

์ด์ œ ByteBuf ์„ธ๊ทธ๋จผํŠธ์˜ ๋ณต์‚ฌ๋ณธ์ด ์›๋ณธ๊ณผ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ์ง€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
ByteBuf copy = buf.copy(0, 14);
System.out.println(copy.toString(utf8));
buf.setByte(0, (byte)'J');
assert buf.getByte(0) != copy.getByte(0);

5.3.9 Read/write operations

์ฝ๊ธฐ/์“ฐ๊ธฐ ์ž‘์—…์—๋Š” ๋‘ ๊ฐ€์ง€ ๋ฒ”์ฃผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ์ง€์ •๋œ ์ธ๋ฑ์Šค์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์ธ๋ฑ์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” get() ๋ฐ set() ์ž‘์—…

  • ์ง€์ •๋œ ์ธ๋ฑ์Šค์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์ ‘๊ทผํ•œ ๋ฐ”์ดํŠธ ์ˆ˜๋งŒํผ ์ธ๋ฑ์Šค๋ฅผ ์กฐ์ •ํ•˜๋Š” read() ๋ฐ write() ์ž‘์—…

๋‹ค์Œ ์˜ˆ์ œ๋Š” get() ๋ฐ set() ๋ฉ”์„œ๋“œ์˜ ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ฃผ๋ฉฐ, ์ด ๋ฉ”์„œ๋“œ๋“ค์ด ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ์ธ๋ฑ์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
System.out.println((char)buf.getByte(0));
int readerIndex = buf.readerIndex();
int writerIndex = buf.writerIndex();
buf.setByte(0, (byte)'B');
System.out.println((char)buf.getByte(0));
assert readerIndex == buf.readerIndex();
assert writerIndex == buf.writerIndex();

์ด์ œ read() ๋ฐ write() ์ž‘์—…์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋“ค์€ ํ˜„์žฌ readerIndex ๋˜๋Š” writerIndex์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ๋Š” ByteBuf๋ฅผ ์ŠคํŠธ๋ฆผ์ฒ˜๋Ÿผ ์ฝ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ read() ๋ฉ”์„œ๋“œ๋Š” ๋Œ€์‘ํ•˜๋Š” write() ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ByteBuf์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ๋Š” read() ๋ฐ write() ๋ฉ”์„œ๋“œ์˜ ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Charset utf8 = Charset.forName("UTF-8");
ByteBuf buf = Unpooled.copiedBuffer("Netty in Action rocks!", utf8);
System.out.println((char)buf.readByte());
int readerIndex = buf.readerIndex();
int writerIndex = buf.writerIndex();
buf.writeByte((byte)'?');
assert readerIndex == buf.readerIndex();
assert writerIndex != buf.writerIndex();

5.3.10 More operations

๋‹ค์Œ ํ‘œ๋Š” ByteBuf์—์„œ ์ œ๊ณตํ•˜๋Š” ์ถ”๊ฐ€์ ์ธ ์œ ์šฉํ•œ ์ž‘์—…๋“ค์„ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.

NameDescription

isReadable()

์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ๋ฐ”์ดํŠธ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์œผ๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

isWritable()

์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ๋ฐ”์ดํŠธ๋ฅผ ์“ธ ์ˆ˜ ์žˆ์œผ๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

readableBytes()

์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

writableBytes()

์“ธ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

capacity()

ByteBuf๊ฐ€ ๋ณด์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

maxCapacity()

ByteBuf๊ฐ€ ๋ณด์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

hasArray()

ByteBuf๊ฐ€ ๋ฐ”์ดํŠธ ๋ฐฐ์—ด๋กœ ์ง€์›๋˜๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

array()

ByteBuf๊ฐ€ ๋ฐ”์ดํŠธ ๋ฐฐ์—ด๋กœ ์ง€์›๋˜๋ฉด ๋ฐ”์ดํŠธ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด UnsupportedOperationException์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

5.4 Interface ByteBufHolder

์šฐ๋ฆฌ๋Š” ์ข…์ข… ์‹ค์ œ ๋ฐ์ดํ„ฐ ํŽ˜์ด๋กœ๋“œ ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์†์„ฑ ๊ฐ’์„ ์ €์žฅํ•ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. HTTP ์‘๋‹ต์€ ์ข‹์€ ์˜ˆ๋กœ, ๋ฐ”์ดํŠธ๋กœ ํ‘œํ˜„๋œ ์ฝ˜ํ…์ธ  ์™ธ์—๋„ ์ƒํƒœ ์ฝ”๋“œ, ์ฟ ํ‚ค ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Netty๋Š” ์ด๋Ÿฌํ•œ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ByteBufHolder๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ByteBufHolder๋Š” ๋˜ํ•œ Netty์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์ธ ๋ฒ„ํผ ํ’€๋ง์„ ์ง€์›ํ•˜๋ฉฐ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ByteBuf๋ฅผ ํ’€์—์„œ ๋นŒ๋ ค์˜ค๊ณ  ์ž๋™์œผ๋กœ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ByteBufHolder๋Š” ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ์™€ ์ฐธ์กฐ ์นด์šดํŒ…์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Table 5.6์€ ReferenceCounted์—์„œ ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๋“ค์„ ์ œ์™ธํ•œ ByteBufHolder์˜ ๋ฉ”์„œ๋“œ๋“ค์„ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.

NameDescription

content()

ByteBufHolder๊ฐ€ ๋ณด์œ ํ•œ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

copy()

ํฌํ•จ๋œ ByteBuf์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜์—ฌ ์ด ByteBufHolder์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

duplicate()

ํฌํ•จ๋œ ByteBuf์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๋Š” ์–•์€ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ByteBufHolder๋Š” ํŽ˜์ด๋กœ๋“œ๋ฅผ ByteBuf์— ์ €์žฅํ•˜๋Š” ๋ฉ”์‹œ์ง€ ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ข‹์€ ์„ ํƒ์ž…๋‹ˆ๋‹ค.

5.5 ByteBuf allocation

์ด ์„น์…˜์—์„œ๋Š” ByteBuf ์ธ์Šคํ„ด์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

5.5.1 On-demand: interface ByteBufAllocator

๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฐ ํ•ด์ œ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด Netty๋Š” ByteBufAllocator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ํ’€๋ง์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ํ’€๋ง์˜ ์‚ฌ์šฉ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋ณ„ ๊ฒฐ์ •์ด๋ฉฐ ByteBuf API์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Channel(๊ฐ Channel์€ ๊ณ ์œ ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ)์ด๋‚˜ ChannelHandler์— ๋ฐ”์ธ๋”ฉ๋œ ChannelHandlerContext์—์„œ ByteBufAllocator๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Channel channel = ...;
ByteBufAllocator allocator = channel.alloc();
....
ChannelHandlerContext ctx = ...;
ByteBufAllocator allocator2 = ctx.alloc();

Netty๋Š” ByteBufAllocator์˜ ๋‘ ๊ฐ€์ง€ ๊ตฌํ˜„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค

PooledByteBufAllocator๋Š” ByteBuf ์ธ์Šคํ„ด์Šค๋ฅผ ํ’€๋งํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋ฅผ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌํ˜„์€ ์—ฌ๋Ÿฌ ์ตœ์‹  ์šด์˜ ์ฒด์ œ์—์„œ ์ฑ„ํƒ๋œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฐฉ๋ฒ•์ธ jemalloc์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

UnpooledByteBufAllocator๋Š” ByteBuf ์ธ์Šคํ„ด์Šค๋ฅผ ํ’€๋งํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Netty๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ PooledByteBufAllocator๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ChannelConfig API๋ฅผ ํ†ตํ•ด ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์‹œ ๋‹ค๋ฅธ ํ• ๋‹น์ž๋ฅผ ์ง€์ •ํ•˜์—ฌ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5.5.2 Unpooled buffers

ByteBufAllocator์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์—†๋Š” ์ƒํ™ฉ๋„ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ Netty๋Š” Unpooled๋ผ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•˜์—ฌ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ •์  ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

NameDescription

buffer()

ํž™ ๊ธฐ๋ฐ˜ ์ €์žฅ์†Œ๋ฅผ ๊ฐ€์ง„ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

buffer(int initialCapacity)

์ดˆ๊ธฐ ์šฉ๋Ÿ‰์„ ๊ฐ€์ง„ ํž™ ๊ธฐ๋ฐ˜ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

buffer(int initialCapacity, int maxCapacity)

์ดˆ๊ธฐ ์šฉ๋Ÿ‰๊ณผ ์ตœ๋Œ€ ์šฉ๋Ÿ‰์„ ๊ฐ€์ง„ ํž™ ๊ธฐ๋ฐ˜ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

directBuffer()

์ง์ ‘ ์ €์žฅ์†Œ๋ฅผ ๊ฐ€์ง„ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

directBuffer(int initialCapacity)

์ดˆ๊ธฐ ์šฉ๋Ÿ‰์„ ๊ฐ€์ง„ ์ง์ ‘ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

directBuffer(int initialCapacity, int maxCapacity)

์ดˆ๊ธฐ ์šฉ๋Ÿ‰๊ณผ ์ตœ๋Œ€ ์šฉ๋Ÿ‰์„ ๊ฐ€์ง„ ์ง์ ‘ ํ’€๋ง๋˜์ง€ ์•Š์€ ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

wrappedBuffer()

์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

copiedBuffer()

์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ByteBuf๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Unpooled ํด๋ž˜์Šค๋Š” ByteBuf๋ฅผ ๋„คํŠธ์›Œํฌ ํ”„๋กœ์ ํŠธ ์™ธ์˜ ๊ณ ์„ฑ๋Šฅ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋ฒ„ํผ API๊ฐ€ ํ•„์š”ํ•œ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ”„๋กœ์ ํŠธ๋Š” Netty์˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

5.5.3 Class ByteBufUtil

ByteBufUtil์€ ByteBuf๋ฅผ ์กฐ์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ์ •์  ํ—ฌํผ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ์ •์  ๋ฉ”์„œ๋“œ๋Š” ์•„๋งˆ๋„ hexdump()์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ByteBuf์˜ ๋‚ด์šฉ์„ 16์ง„์ˆ˜๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋””๋ฒ„๊น… ๋ชฉ์ ์œผ๋กœ ByteBuf์˜ ๋‚ด์šฉ์„ ๋กœ๊น…ํ•˜๋Š” ์ƒํ™ฉ ๋“ฑ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. 16์ง„์ˆ˜ ํ‘œํ˜„์€ ๋ฐ”์ดํŠธ ๊ฐ’์„ ์ง์ ‘ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ์œ ์šฉํ•œ ๋กœ๊ทธ ํ•ญ๋ชฉ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์‹ค์ œ ๋ฐ”์ดํŠธ ํ‘œํ˜„์œผ๋กœ ์‰ฝ๊ฒŒ ๋ณ€ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ boolean equals(ByteBuf, ByteBuf) ๋ฉ”์„œ๋“œ๋Š” ๋‘ ByteBuf ์ธ์Šคํ„ด์Šค์˜ ๋™๋“ฑ์„ฑ์„ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. ByteBufUtil์˜ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ByteBuf ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5.6 Reference counting

์ฐธ์กฐ ์นด์šดํŒ…์€ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ์˜ํ•ด ๋” ์ด์ƒ ์ฐธ์กฐ๋˜์ง€ ์•Š์„ ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ๋ณด์œ ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๊ณผ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

์ฐธ์กฐ ์นด์šดํŒ…์˜ ์•„์ด๋””์–ด๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ๊ฐ์ฒด์— ๋Œ€ํ•œ ํ™œ์„ฑ ์ฐธ์กฐ ์ˆ˜๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ReferenceCounted ๊ตฌํ˜„ ์ธ์Šคํ„ด์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ 1์˜ ํ™œ์„ฑ ์ฐธ์กฐ ์นด์šดํŠธ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0๋ณด๋‹ค ํฐ ๋™์•ˆ ๊ฐ์ฒด๋Š” ํ•ด์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ™œ์„ฑ ์ฐธ์กฐ ์ˆ˜๊ฐ€ 0์ด ๋˜๋ฉด ์ธ์Šคํ„ด์Šค๋Š” ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐ ์นด์šดํŒ…์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๋Š” PooledByteBufAllocator์™€ ๊ฐ™์€ ํ’€๋ง ๊ตฌํ˜„์— ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

Channel channel = ...;
ByteBufAllocator allocator = channel.alloc();
ByteBuf buffer = allocator.directBuffer();
assert buffer.refCnt() == 1;
ByteBuf buffer = ...;
boolean released = buffer.release();

์ฐธ์กฐ๋œ ๊ฐ์ฒด๊ฐ€ ํ•ด์ œ๋œ ํ›„์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•˜๋ฉด IllegalReferenceCountException์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ํด๋ž˜์Šค๋Š” ์ž์‹ ์˜ ๋ฐฉ์‹์œผ๋กœ ์ฐธ์กฐ ์นด์šดํŒ… ๊ณ„์•ฝ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Last updated