Remove DefaultCompositeByteBuf.lastAccessed and use binary search instead
- Fixes #1364 - Even if a user creates a duplicate/slice, lastAccessed was shared between the derived buffers and it's updated even by a read operation, which made multithread access impossible
This commit is contained in:
parent
7140e4e63b
commit
f92cfba388
@ -49,8 +49,6 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf imp
|
|||||||
private final List<Component> components = new ArrayList<Component>();
|
private final List<Component> components = new ArrayList<Component>();
|
||||||
private final int maxNumComponents;
|
private final int maxNumComponents;
|
||||||
|
|
||||||
private Component lastAccessed;
|
|
||||||
private int lastAccessedId;
|
|
||||||
private boolean freed;
|
private boolean freed;
|
||||||
private Queue<ByteBuf> suspendedDeallocations;
|
private Queue<ByteBuf> suspendedDeallocations;
|
||||||
|
|
||||||
@ -284,9 +282,6 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf imp
|
|||||||
|
|
||||||
private void updateComponentOffsets(int cIndex) {
|
private void updateComponentOffsets(int cIndex) {
|
||||||
Component c = components.get(cIndex);
|
Component c = components.get(cIndex);
|
||||||
lastAccessed = c;
|
|
||||||
lastAccessedId = cIndex;
|
|
||||||
|
|
||||||
if (cIndex == 0) {
|
if (cIndex == 0) {
|
||||||
c.offset = 0;
|
c.offset = 0;
|
||||||
c.endOffset = c.length;
|
c.endOffset = c.length;
|
||||||
@ -508,37 +503,19 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf imp
|
|||||||
assert !freed;
|
assert !freed;
|
||||||
checkIndex(offset);
|
checkIndex(offset);
|
||||||
|
|
||||||
Component c = lastAccessed;
|
for (int low = 0, high = components.size(); low <= high;) {
|
||||||
if (c == null) {
|
int mid = low + high >>> 1;
|
||||||
lastAccessed = c = components.get(0);
|
Component c = components.get(mid);
|
||||||
}
|
if (offset >= c.endOffset) {
|
||||||
if (offset >= c.offset) {
|
low = mid + 1;
|
||||||
if (offset < c.endOffset) {
|
} else if (offset < c.offset) {
|
||||||
return lastAccessedId;
|
high = mid - 1;
|
||||||
}
|
|
||||||
|
|
||||||
// Search right
|
|
||||||
for (int i = lastAccessedId + 1; i < components.size(); i ++) {
|
|
||||||
c = components.get(i);
|
|
||||||
if (offset < c.endOffset) {
|
|
||||||
lastAccessedId = i;
|
|
||||||
lastAccessed = c;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Search left
|
return mid;
|
||||||
for (int i = lastAccessedId - 1; i >= 0; i --) {
|
|
||||||
c = components.get(i);
|
|
||||||
if (offset >= c.offset) {
|
|
||||||
lastAccessedId = i;
|
|
||||||
lastAccessed = c;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalStateException("should not reach here - concurrent modification?");
|
throw new Error("should not reach here");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -982,38 +959,22 @@ public class DefaultCompositeByteBuf extends AbstractReferenceCountedByteBuf imp
|
|||||||
assert !freed;
|
assert !freed;
|
||||||
checkIndex(offset);
|
checkIndex(offset);
|
||||||
|
|
||||||
Component c = lastAccessed;
|
assert !freed;
|
||||||
if (c == null) {
|
checkIndex(offset);
|
||||||
lastAccessed = c = components.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= c.offset) {
|
for (int low = 0, high = components.size(); low <= high;) {
|
||||||
if (offset < c.endOffset) {
|
int mid = low + high >>> 1;
|
||||||
return c;
|
Component c = components.get(mid);
|
||||||
}
|
if (offset >= c.endOffset) {
|
||||||
|
low = mid + 1;
|
||||||
// Search right
|
} else if (offset < c.offset) {
|
||||||
for (int i = lastAccessedId + 1; i < components.size(); i ++) {
|
high = mid - 1;
|
||||||
c = components.get(i);
|
|
||||||
if (offset < c.endOffset) {
|
|
||||||
lastAccessedId = i;
|
|
||||||
lastAccessed = c;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Search left
|
|
||||||
for (int i = lastAccessedId - 1; i >= 0; i --) {
|
|
||||||
c = components.get(i);
|
|
||||||
if (offset >= c.offset) {
|
|
||||||
lastAccessedId = i;
|
|
||||||
lastAccessed = c;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException("should not reach here - concurrent modification?");
|
throw new Error("should not reach here");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user