@@ -615,6 +615,7 @@ public CompositeByteBuf removeComponent(int cIndex) {
615615 Component comp = components [cIndex ];
616616 if (lastAccessed == comp ) {
617617 lastAccessed = null ;
618+ lastAccessedIndex = 0 ;
618619 }
619620 comp .free ();
620621 removeComp (cIndex );
@@ -646,6 +647,7 @@ public CompositeByteBuf removeComponents(int cIndex, int numComponents) {
646647 }
647648 if (lastAccessed == c ) {
648649 lastAccessed = null ;
650+ lastAccessedIndex = 0 ;
649651 }
650652 c .free ();
651653 }
@@ -856,6 +858,7 @@ public CompositeByteBuf capacity(int newCapacity) {
856858 }
857859 } else if (newCapacity < oldCapacity ) {
858860 lastAccessed = null ;
861+ lastAccessedIndex = 0 ;
859862 int i = size - 1 ;
860863 for (int bytesToTrim = oldCapacity - newCapacity ; i >= 0 ; i --) {
861864 Component c = components [i ];
@@ -952,20 +955,36 @@ public int toByteIndex(int cIndex) {
952955 @ Override
953956 public byte getByte (int index ) {
954957 Component c = findComponent (index );
955- return c .buf .getByte (c .idx (index ));
958+ return c .abuf != null ? c .abuf ._getByte (c .idx (index )) : c .buf .getByte (c .idx (index ));
959+ }
960+
961+ @ Override
962+ public byte readByte () {
963+ checkReadableBytes (1 );
964+ int rIdx = readerIndex ;
965+ Component c = lastAccessed ;
966+ if (c == null ) {
967+ c = findIt (rIdx );
968+ } else if (rIdx >= c .endOffset ) {
969+ c = findComponentForRead (rIdx );
970+ } else if (rIdx < c .offset ) {
971+ c = findIt (rIdx );
972+ }
973+ readerIndex = rIdx + 1 ;
974+ return c .abuf != null ? c .abuf ._getByte (rIdx + c .adjustment ) : c .buf .getByte (rIdx + c .adjustment );
956975 }
957976
958977 @ Override
959978 protected byte _getByte (int index ) {
960979 Component c = findComponent0 (index );
961- return c .buf .getByte (c .idx (index ));
980+ return c .abuf != null ? c . abuf . _getByte ( c . idx ( index )) : c . buf .getByte (c .idx (index ));
962981 }
963982
964983 @ Override
965984 protected short _getShort (int index ) {
966985 Component c = findComponent0 (index );
967986 if (index + 2 <= c .endOffset ) {
968- return c .buf .getShort (c .idx (index ));
987+ return c .abuf != null ? c . abuf . _getShort ( c . idx ( index )) : c . buf .getShort (c .idx (index ));
969988 } else if (order () == ByteOrder .BIG_ENDIAN ) {
970989 return (short ) ((_getByte (index ) & 0xff ) << 8 | _getByte (index + 1 ) & 0xff );
971990 } else {
@@ -977,7 +996,7 @@ protected short _getShort(int index) {
977996 protected short _getShortLE (int index ) {
978997 Component c = findComponent0 (index );
979998 if (index + 2 <= c .endOffset ) {
980- return c .buf .getShortLE (c .idx (index ));
999+ return c .abuf != null ? c . abuf . _getShortLE ( c . idx ( index )) : c . buf .getShortLE (c .idx (index ));
9811000 } else if (order () == ByteOrder .BIG_ENDIAN ) {
9821001 return (short ) (_getByte (index ) & 0xff | (_getByte (index + 1 ) & 0xff ) << 8 );
9831002 } else {
@@ -989,7 +1008,8 @@ protected short _getShortLE(int index) {
9891008 protected int _getUnsignedMedium (int index ) {
9901009 Component c = findComponent0 (index );
9911010 if (index + 3 <= c .endOffset ) {
992- return c .buf .getUnsignedMedium (c .idx (index ));
1011+ return c .abuf != null ? c .abuf ._getUnsignedMedium (c .idx (index ))
1012+ : c .buf .getUnsignedMedium (c .idx (index ));
9931013 } else if (order () == ByteOrder .BIG_ENDIAN ) {
9941014 return (_getShort (index ) & 0xffff ) << 8 | _getByte (index + 2 ) & 0xff ;
9951015 } else {
@@ -1001,7 +1021,8 @@ protected int _getUnsignedMedium(int index) {
10011021 protected int _getUnsignedMediumLE (int index ) {
10021022 Component c = findComponent0 (index );
10031023 if (index + 3 <= c .endOffset ) {
1004- return c .buf .getUnsignedMediumLE (c .idx (index ));
1024+ return c .abuf != null ? c .abuf ._getUnsignedMediumLE (c .idx (index ))
1025+ : c .buf .getUnsignedMediumLE (c .idx (index ));
10051026 } else if (order () == ByteOrder .BIG_ENDIAN ) {
10061027 return _getShortLE (index ) & 0xffff | (_getByte (index + 2 ) & 0xff ) << 16 ;
10071028 } else {
@@ -1013,7 +1034,7 @@ protected int _getUnsignedMediumLE(int index) {
10131034 protected int _getInt (int index ) {
10141035 Component c = findComponent0 (index );
10151036 if (index + 4 <= c .endOffset ) {
1016- return c .buf .getInt (c .idx (index ));
1037+ return c .abuf != null ? c . abuf . _getInt ( c . idx ( index )) : c . buf .getInt (c .idx (index ));
10171038 } else if (order () == ByteOrder .BIG_ENDIAN ) {
10181039 return (_getShort (index ) & 0xffff ) << 16 | _getShort (index + 2 ) & 0xffff ;
10191040 } else {
@@ -1025,7 +1046,7 @@ protected int _getInt(int index) {
10251046 protected int _getIntLE (int index ) {
10261047 Component c = findComponent0 (index );
10271048 if (index + 4 <= c .endOffset ) {
1028- return c .buf .getIntLE (c .idx (index ));
1049+ return c .abuf != null ? c . abuf . _getIntLE ( c . idx ( index )) : c . buf .getIntLE (c .idx (index ));
10291050 } else if (order () == ByteOrder .BIG_ENDIAN ) {
10301051 return _getShortLE (index ) & 0xffff | (_getShortLE (index + 2 ) & 0xffff ) << 16 ;
10311052 } else {
@@ -1037,7 +1058,7 @@ protected int _getIntLE(int index) {
10371058 protected long _getLong (int index ) {
10381059 Component c = findComponent0 (index );
10391060 if (index + 8 <= c .endOffset ) {
1040- return c .buf .getLong (c .idx (index ));
1061+ return c .abuf != null ? c . abuf . _getLong ( c . idx ( index )) : c . buf .getLong (c .idx (index ));
10411062 } else if (order () == ByteOrder .BIG_ENDIAN ) {
10421063 return (_getInt (index ) & 0xffffffffL ) << 32 | _getInt (index + 4 ) & 0xffffffffL ;
10431064 } else {
@@ -1049,7 +1070,7 @@ protected long _getLong(int index) {
10491070 protected long _getLongLE (int index ) {
10501071 Component c = findComponent0 (index );
10511072 if (index + 8 <= c .endOffset ) {
1052- return c .buf .getLongLE (c .idx (index ));
1073+ return c .abuf != null ? c . abuf . _getLongLE ( c . idx ( index )) : c . buf .getLongLE (c .idx (index ));
10531074 } else if (order () == ByteOrder .BIG_ENDIAN ) {
10541075 return _getIntLE (index ) & 0xffffffffL | (_getIntLE (index + 4 ) & 0xffffffffL ) << 32 ;
10551076 } else {
@@ -1180,14 +1201,22 @@ public CompositeByteBuf getBytes(int index, OutputStream out, int length) throws
11801201 @ Override
11811202 public CompositeByteBuf setByte (int index , int value ) {
11821203 Component c = findComponent (index );
1183- c .buf .setByte (c .idx (index ), value );
1204+ if (c .abuf != null ) {
1205+ c .abuf ._setByte (c .idx (index ), value );
1206+ } else {
1207+ c .buf .setByte (c .idx (index ), value );
1208+ }
11841209 return this ;
11851210 }
11861211
11871212 @ Override
11881213 protected void _setByte (int index , int value ) {
11891214 Component c = findComponent0 (index );
1190- c .buf .setByte (c .idx (index ), value );
1215+ if (c .abuf != null ) {
1216+ c .abuf ._setByte (c .idx (index ), value );
1217+ } else {
1218+ c .buf .setByte (c .idx (index ), value );
1219+ }
11911220 }
11921221
11931222 @ Override
@@ -1201,7 +1230,11 @@ public CompositeByteBuf setShort(int index, int value) {
12011230 protected void _setShort (int index , int value ) {
12021231 Component c = findComponent0 (index );
12031232 if (index + 2 <= c .endOffset ) {
1204- c .buf .setShort (c .idx (index ), value );
1233+ if (c .abuf != null ) {
1234+ c .abuf ._setShort (c .idx (index ), value );
1235+ } else {
1236+ c .buf .setShort (c .idx (index ), value );
1237+ }
12051238 } else if (order () == ByteOrder .BIG_ENDIAN ) {
12061239 _setByte (index , (byte ) (value >>> 8 ));
12071240 _setByte (index + 1 , (byte ) value );
@@ -1215,7 +1248,11 @@ protected void _setShort(int index, int value) {
12151248 protected void _setShortLE (int index , int value ) {
12161249 Component c = findComponent0 (index );
12171250 if (index + 2 <= c .endOffset ) {
1218- c .buf .setShortLE (c .idx (index ), value );
1251+ if (c .abuf != null ) {
1252+ c .abuf ._setShortLE (c .idx (index ), value );
1253+ } else {
1254+ c .buf .setShortLE (c .idx (index ), value );
1255+ }
12191256 } else if (order () == ByteOrder .BIG_ENDIAN ) {
12201257 _setByte (index , (byte ) value );
12211258 _setByte (index + 1 , (byte ) (value >>> 8 ));
@@ -1236,7 +1273,11 @@ public CompositeByteBuf setMedium(int index, int value) {
12361273 protected void _setMedium (int index , int value ) {
12371274 Component c = findComponent0 (index );
12381275 if (index + 3 <= c .endOffset ) {
1239- c .buf .setMedium (c .idx (index ), value );
1276+ if (c .abuf != null ) {
1277+ c .abuf ._setMedium (c .idx (index ), value );
1278+ } else {
1279+ c .buf .setMedium (c .idx (index ), value );
1280+ }
12401281 } else if (order () == ByteOrder .BIG_ENDIAN ) {
12411282 _setShort (index , (short ) (value >> 8 ));
12421283 _setByte (index + 2 , (byte ) value );
@@ -1250,7 +1291,11 @@ protected void _setMedium(int index, int value) {
12501291 protected void _setMediumLE (int index , int value ) {
12511292 Component c = findComponent0 (index );
12521293 if (index + 3 <= c .endOffset ) {
1253- c .buf .setMediumLE (c .idx (index ), value );
1294+ if (c .abuf != null ) {
1295+ c .abuf ._setMediumLE (c .idx (index ), value );
1296+ } else {
1297+ c .buf .setMediumLE (c .idx (index ), value );
1298+ }
12541299 } else if (order () == ByteOrder .BIG_ENDIAN ) {
12551300 _setShortLE (index , (short ) value );
12561301 _setByte (index + 2 , (byte ) (value >>> 16 ));
@@ -1271,7 +1316,11 @@ public CompositeByteBuf setInt(int index, int value) {
12711316 protected void _setInt (int index , int value ) {
12721317 Component c = findComponent0 (index );
12731318 if (index + 4 <= c .endOffset ) {
1274- c .buf .setInt (c .idx (index ), value );
1319+ if (c .abuf != null ) {
1320+ c .abuf ._setInt (c .idx (index ), value );
1321+ } else {
1322+ c .buf .setInt (c .idx (index ), value );
1323+ }
12751324 } else if (order () == ByteOrder .BIG_ENDIAN ) {
12761325 _setShort (index , (short ) (value >>> 16 ));
12771326 _setShort (index + 2 , (short ) value );
@@ -1285,7 +1334,11 @@ protected void _setInt(int index, int value) {
12851334 protected void _setIntLE (int index , int value ) {
12861335 Component c = findComponent0 (index );
12871336 if (index + 4 <= c .endOffset ) {
1288- c .buf .setIntLE (c .idx (index ), value );
1337+ if (c .abuf != null ) {
1338+ c .abuf ._setIntLE (c .idx (index ), value );
1339+ } else {
1340+ c .buf .setIntLE (c .idx (index ), value );
1341+ }
12891342 } else if (order () == ByteOrder .BIG_ENDIAN ) {
12901343 _setShortLE (index , (short ) value );
12911344 _setShortLE (index + 2 , (short ) (value >>> 16 ));
@@ -1306,7 +1359,11 @@ public CompositeByteBuf setLong(int index, long value) {
13061359 protected void _setLong (int index , long value ) {
13071360 Component c = findComponent0 (index );
13081361 if (index + 8 <= c .endOffset ) {
1309- c .buf .setLong (c .idx (index ), value );
1362+ if (c .abuf != null ) {
1363+ c .abuf ._setLong (c .idx (index ), value );
1364+ } else {
1365+ c .buf .setLong (c .idx (index ), value );
1366+ }
13101367 } else if (order () == ByteOrder .BIG_ENDIAN ) {
13111368 _setInt (index , (int ) (value >>> 32 ));
13121369 _setInt (index + 4 , (int ) value );
@@ -1320,7 +1377,11 @@ protected void _setLong(int index, long value) {
13201377 protected void _setLongLE (int index , long value ) {
13211378 Component c = findComponent0 (index );
13221379 if (index + 8 <= c .endOffset ) {
1323- c .buf .setLongLE (c .idx (index ), value );
1380+ if (c .abuf != null ) {
1381+ c .abuf ._setLongLE (c .idx (index ), value );
1382+ } else {
1383+ c .buf .setLongLE (c .idx (index ), value );
1384+ }
13241385 } else if (order () == ByteOrder .BIG_ENDIAN ) {
13251386 _setIntLE (index , (int ) value );
13261387 _setIntLE (index + 4 , (int ) (value >>> 32 ));
@@ -1613,6 +1674,7 @@ public ByteBuf internalComponentAtOffset(int offset) {
16131674
16141675 // weak cache - check it first when looking for component
16151676 private Component lastAccessed ;
1677+ private int lastAccessedIndex ;
16161678
16171679 private Component findComponent (int offset ) {
16181680 Component la = lastAccessed ;
@@ -1632,6 +1694,22 @@ private Component findComponent0(int offset) {
16321694 return findIt (offset );
16331695 }
16341696
1697+ /**
1698+ * Sequential-read fast path: try the next component(s) before falling back to binary search.
1699+ */
1700+ private Component findComponentForRead (int offset ) {
1701+ int cc = componentCount ;
1702+ for (int next = lastAccessedIndex + 1 ; next < cc ; next ++) {
1703+ Component c = components [next ];
1704+ if (c .endOffset > c .offset ) {
1705+ lastAccessed = c ;
1706+ lastAccessedIndex = next ;
1707+ return c ;
1708+ }
1709+ }
1710+ return findIt (offset );
1711+ }
1712+
16351713 private Component findIt (int offset ) {
16361714 for (int low = 0 , high = componentCount ; low <= high ;) {
16371715 int mid = low + high >>> 1 ;
@@ -1646,6 +1724,7 @@ private Component findIt(int offset) {
16461724 high = mid - 1 ;
16471725 } else {
16481726 lastAccessed = c ;
1727+ lastAccessedIndex = mid ;
16491728 return c ;
16501729 }
16511730 }
@@ -1785,6 +1864,7 @@ private void consolidate0(int cIndex, int numComponents) {
17851864 components [i ].transferTo (consolidated );
17861865 }
17871866 lastAccessed = null ;
1867+ lastAccessedIndex = 0 ;
17881868 removeCompRange (cIndex + 1 , endCIndex );
17891869 components [cIndex ] = newComponent (consolidated , 0 );
17901870 if (cIndex != 0 || numComponents != componentCount ) {
@@ -1809,6 +1889,7 @@ public CompositeByteBuf discardReadComponents() {
18091889 components [i ].free ();
18101890 }
18111891 lastAccessed = null ;
1892+ lastAccessedIndex = 0 ;
18121893 clearComps ();
18131894 setIndex (0 , 0 );
18141895 adjustMarkers (readerIndex );
@@ -1831,6 +1912,7 @@ public CompositeByteBuf discardReadComponents() {
18311912 Component la = lastAccessed ;
18321913 if (la != null && la .endOffset <= readerIndex ) {
18331914 lastAccessed = null ;
1915+ lastAccessedIndex = 0 ;
18341916 }
18351917 removeCompRange (0 , firstComponentId );
18361918
@@ -1857,6 +1939,7 @@ public CompositeByteBuf discardReadBytes() {
18571939 components [i ].free ();
18581940 }
18591941 lastAccessed = null ;
1942+ lastAccessedIndex = 0 ;
18601943 clearComps ();
18611944 setIndex (0 , 0 );
18621945 adjustMarkers (readerIndex );
@@ -1888,6 +1971,7 @@ public CompositeByteBuf discardReadBytes() {
18881971 Component la = lastAccessed ;
18891972 if (la != null && la .endOffset <= readerIndex ) {
18901973 lastAccessed = null ;
1974+ lastAccessedIndex = 0 ;
18911975 }
18921976
18931977 removeCompRange (0 , firstComponentId );
@@ -1913,6 +1997,7 @@ public String toString() {
19131997 private static final class Component {
19141998 final ByteBuf srcBuf ; // the originally added buffer
19151999 final ByteBuf buf ; // srcBuf unwrapped zero or more times
2000+ final AbstractByteBuf abuf ; // buf cast to AbstractByteBuf, or null if not an instance
19162001
19172002 int srcAdjustment ; // index of the start of this CompositeByteBuf relative to srcBuf
19182003 int adjustment ; // index of the start of this CompositeByteBuf relative to buf
@@ -1927,6 +2012,7 @@ private static final class Component {
19272012 this .srcBuf = srcBuf ;
19282013 this .srcAdjustment = srcOffset - offset ;
19292014 this .buf = buf ;
2015+ this .abuf = buf instanceof AbstractByteBuf ? (AbstractByteBuf ) buf : null ;
19302016 this .adjustment = bufOffset - offset ;
19312017 this .offset = offset ;
19322018 this .endOffset = offset + len ;
0 commit comments