Skip to content

Commit 5c92d1d

Browse files
committed
added LinkedBufferInput#copyReferencedBuffer
1 parent aa884c4 commit 5c92d1d

File tree

2 files changed

+137
-1
lines changed

2 files changed

+137
-1
lines changed

src/main/java/org/msgpack/io/LinkedBufferInput.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.IOException;
2121
import java.io.EOFException;
2222
import java.util.LinkedList;
23+
import java.util.Iterator;
2324
import java.nio.ByteBuffer;
2425

2526
public class LinkedBufferInput extends AbstractInput {
@@ -315,7 +316,7 @@ public void feed(ByteBuffer buf, boolean nocopy) {
315316
}
316317

317318
public void clear() {
318-
if (writable > 0) {
319+
if (writable >= 0) {
319320
ByteBuffer bb = link.getLast();
320321
link.clear();
321322
bb.position(0);
@@ -328,6 +329,46 @@ public void clear() {
328329
}
329330
}
330331

332+
public void copyReferencedBuffer() {
333+
if (link.isEmpty()) {
334+
return;
335+
}
336+
337+
int size = 0;
338+
for(ByteBuffer bb : link) {
339+
size += bb.remaining();
340+
}
341+
if (size == 0) {
342+
return;
343+
}
344+
345+
if (writable >= 0) {
346+
ByteBuffer last = link.removeLast();
347+
byte[] copy = new byte[size - last.remaining()];
348+
int off = 0;
349+
for(ByteBuffer bb : link) {
350+
int len = bb.remaining();
351+
bb.get(copy, off, len);
352+
off += len;
353+
}
354+
link.clear();
355+
link.add(ByteBuffer.wrap(copy));
356+
link.add(last);
357+
358+
} else {
359+
byte[] copy = new byte[size];
360+
int off = 0;
361+
for(ByteBuffer bb : link) {
362+
int len = bb.remaining();
363+
bb.get(copy, off, len);
364+
off += len;
365+
}
366+
link.clear();
367+
link.add(ByteBuffer.wrap(copy));
368+
writable = 0;
369+
}
370+
}
371+
331372
public void close() {
332373
}
333374
}

src/test/java/org/msgpack/io/TestLinkedBufferInput.java

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,101 @@ public void testClear() throws IOException {
439439
}
440440
}
441441

442+
@Test
443+
public void testClearRecycle() throws IOException {
444+
byte[] data = new byte[8];
445+
data[0] = (byte)1;
446+
data[2] = (byte)1;
447+
data[4] = (byte)1;
448+
449+
LinkedBufferInput b = new LinkedBufferInput(16);
450+
451+
b.feed(data);
452+
assertEquals(1, b.link.size());
453+
assertEquals(8, b.writable);
454+
b.clear();
455+
assertEquals(1, b.link.size());
456+
assertEquals(16, b.writable);
457+
458+
b.feed(data);
459+
b.feed(data);
460+
assertEquals(1, b.link.size());
461+
assertEquals(0, b.writable);
462+
b.clear();
463+
assertEquals(1, b.link.size());
464+
assertEquals(16, b.writable);
465+
}
466+
467+
@Test
468+
public void testCopyReferencedBuffer() throws IOException {
469+
byte[] data = new byte[16];
470+
data[0] = (byte)4;
471+
data[3] = (byte)5;
472+
data[6] = (byte)6;
473+
data[10] = (byte)7;
474+
475+
LinkedBufferInput b = new LinkedBufferInput(32);
476+
int n;
477+
byte[] buf = new byte[16];
478+
479+
b.feed(data, true);
480+
b.feed(data, true);
481+
b.feed(data, true);
482+
assertEquals(3, b.link.size());
483+
assertEquals(-1, b.writable);
484+
485+
b.copyReferencedBuffer();
486+
assertEquals(1, b.link.size());
487+
assertEquals(0, b.writable);
488+
489+
n = b.read(buf, 0, 16);
490+
assertEquals(n, 16);
491+
assertArrayEquals(data, buf);
492+
493+
n = b.read(buf, 0, 16);
494+
assertEquals(n, 16);
495+
assertArrayEquals(data, buf);
496+
497+
n = b.read(buf, 0, 16);
498+
assertEquals(n, 16);
499+
assertArrayEquals(data, buf);
500+
}
501+
502+
@Test
503+
public void testCopyReferencedBufferOptimized() throws IOException {
504+
byte[] data = new byte[16];
505+
data[0] = (byte)4;
506+
data[3] = (byte)5;
507+
data[6] = (byte)6;
508+
data[10] = (byte)7;
509+
510+
LinkedBufferInput b = new LinkedBufferInput(32);
511+
int n;
512+
byte[] buf = new byte[16];
513+
514+
b.feed(data, true);
515+
b.feed(data, true);
516+
b.feed(data); // buffer allocated
517+
assertEquals(3, b.link.size());
518+
assertEquals(16, b.writable);
519+
520+
b.copyReferencedBuffer();
521+
assertEquals(2, b.link.size());
522+
assertEquals(16, b.writable);
523+
524+
n = b.read(buf, 0, 16);
525+
assertEquals(n, 16);
526+
assertArrayEquals(data, buf);
527+
528+
n = b.read(buf, 0, 16);
529+
assertEquals(n, 16);
530+
assertArrayEquals(data, buf);
531+
532+
n = b.read(buf, 0, 16);
533+
assertEquals(n, 16);
534+
assertArrayEquals(data, buf);
535+
}
536+
442537
@Test
443538
public void testBufferRecycleByteArray() throws IOException {
444539
byte[] data = new byte[16];

0 commit comments

Comments
 (0)