Skip to content

Commit b10a089

Browse files
committed
add test on Writable FragmentedSubIO + fix it
1 parent 8fdd175 commit b10a089

File tree

3 files changed

+80
-18
lines changed

3 files changed

+80
-18
lines changed

net.lecousin.core/src/main/java/net/lecousin/framework/io/FragmentedSubIO.java

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ protected ISynchronizationPoint<IOException> canStartWriting() {
359359
protected int writeSync(long pos, ByteBuffer buffer) throws IOException {
360360
Iterator<RangeLong> it = fragments.iterator();
361361
long p = 0;
362+
int total = 0;
362363
while (it.hasNext()) {
363364
RangeLong r = it.next();
364365
long s = r.max - r.min + 1;
@@ -376,9 +377,13 @@ protected int writeSync(long pos, ByteBuffer buffer) throws IOException {
376377
} else {
377378
len = ((IO.Writable.Seekable)io).writeSync(r.min + start, buffer);
378379
}
379-
return len;
380+
total += len;
381+
pos += len;
382+
p += s;
383+
if (!buffer.hasRemaining())
384+
return total;
380385
}
381-
return 0;
386+
return total;
382387
}
383388

384389
protected AsyncWork<Integer, IOException> writeAsync(long pos, ByteBuffer buffer, RunnableWithParameter<Pair<Integer, IOException>> ondone) {
@@ -391,26 +396,40 @@ protected AsyncWork<Integer, IOException> writeAsync(long pos, ByteBuffer buffer
391396
p += s;
392397
continue;
393398
}
394-
long start = pos - p;
395-
int len = buffer.remaining();
396-
if (start + len > s) {
397-
int prevLimit = buffer.limit();
398-
buffer.limit((int)(prevLimit - ((start + len) - s)));
399-
return ((IO.Writable.Seekable)io).writeAsync(r.min + start, buffer,
400-
new RunnableWithParameter<Pair<Integer,IOException>>() {
401-
@Override
402-
public void run(Pair<Integer, IOException> param) {
403-
buffer.limit(prevLimit);
404-
if (ondone != null) ondone.run(param);
405-
}
406-
});
407-
}
408-
return operation(((IO.Writable.Seekable)io).writeAsync(r.min + start, buffer, ondone));
399+
AsyncWork<Integer,IOException> sp = new AsyncWork<>();
400+
writeAsync(it, r, p, 0, pos, buffer, ondone, sp);
401+
return operation(sp);
409402
}
410403
AsyncWork<Integer,IOException> sp = new AsyncWork<>();
411404
if (ondone != null) ondone.run(new Pair<>(Integer.valueOf(0), null));
412405
sp.unblockSuccess(Integer.valueOf(0));
413406
return sp;
414407
}
415408

409+
protected void writeAsync(
410+
Iterator<RangeLong> it, RangeLong r, long p, int done, long pos,
411+
ByteBuffer buffer, RunnableWithParameter<Pair<Integer, IOException>> ondone, AsyncWork<Integer,IOException> sp
412+
) {
413+
long start = pos - p;
414+
int len = buffer.remaining();
415+
long s = r.max - r.min + 1;
416+
if (start + len > s) {
417+
int prevLimit = buffer.limit();
418+
buffer.limit((int)(prevLimit - ((start + len) - s)));
419+
IOUtil.listenOnDone(((IO.Writable.Seekable)io).writeAsync(r.min + start, buffer), (nb) -> {
420+
buffer.limit(prevLimit);
421+
int i = nb.intValue();
422+
if (!buffer.hasRemaining() || !it.hasNext()) {
423+
IOUtil.success(Integer.valueOf(i), sp, ondone);
424+
return;
425+
}
426+
writeAsync(it, it.next(), p + s, done + i, pos + i, buffer, ondone, sp);
427+
}, sp, ondone);
428+
return;
429+
}
430+
IOUtil.listenOnDone(((IO.Writable.Seekable)io).writeAsync(r.min + start, buffer), (nb) -> {
431+
IOUtil.success(Integer.valueOf(nb.intValue() + done), sp, ondone);
432+
}, sp, ondone);
433+
}
434+
416435
}

net.lecousin.core/src/test/java/net/lecousin/framework/core/test/io/TestReadWrite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public <T extends IO.Readable.Seekable & IO.Writable.Seekable> void testWriteThe
4646
buf.position(0);
4747
int nb = io.writeSync(buf);
4848
if (nb != testBuf.length)
49-
throw new Exception("Write only " + nb + " bytes");
49+
throw new Exception("Write only " + nb + " bytes for buffer " + i);
5050
if (buf.remaining() > 0)
5151
throw new Exception("Buffer not fully consumed by write operation");
5252
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package net.lecousin.framework.core.tests.io;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.util.Collection;
6+
7+
import org.junit.runner.RunWith;
8+
import org.junit.runners.Parameterized;
9+
import org.junit.runners.Parameterized.Parameters;
10+
11+
import net.lecousin.framework.concurrent.Task;
12+
import net.lecousin.framework.core.test.io.TestFragmented;
13+
import net.lecousin.framework.core.test.io.TestFragmented.FragmentedFile;
14+
import net.lecousin.framework.core.test.io.TestReadWrite;
15+
import net.lecousin.framework.io.FileIO;
16+
import net.lecousin.framework.io.FragmentedSubIO;
17+
18+
@RunWith(Parameterized.class)
19+
public class TestFragmentedSubIOReadWrite extends TestReadWrite {
20+
21+
@Parameters
22+
public static Collection<Object[]> parameters() throws IOException {
23+
return TestFragmented.generateTestCases();
24+
}
25+
26+
public TestFragmentedSubIOReadWrite(FragmentedFile f) {
27+
super(f.testBuf, f.nbBuf);
28+
this.f = f;
29+
}
30+
31+
private FragmentedFile f;
32+
33+
@SuppressWarnings("unchecked")
34+
@Override
35+
protected FragmentedSubIO.ReadWrite openReadWrite() throws Exception {
36+
File tmpFile = File.createTempFile("test", "fragmentedsubio.rw");
37+
tmpFile.deleteOnExit();
38+
FileIO.ReadWrite fio = new FileIO.ReadWrite(tmpFile, Task.PRIORITY_NORMAL);
39+
fio.setSizeSync(f.file.length());
40+
return new FragmentedSubIO.ReadWrite(fio, f.fragments, true, "fragmented IO");
41+
}
42+
43+
}

0 commit comments

Comments
 (0)