Skip to content

Commit c0e5737

Browse files
committed
Support for delta processing - 38
1 parent 2791547 commit c0e5737

9 files changed

Lines changed: 202 additions & 9 deletions

File tree

modules/deltahex-delta/src/main/java/org/exbin/deltahex/delta/DeltaDocument.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@
1818
import java.io.IOException;
1919
import java.io.InputStream;
2020
import java.io.OutputStream;
21+
import java.util.ArrayList;
22+
import java.util.List;
2123
import org.exbin.deltahex.delta.list.DefaultDoublyLinkedList;
2224
import org.exbin.utils.binary_data.BinaryData;
2325
import org.exbin.utils.binary_data.EditableBinaryData;
2426

2527
/**
26-
* Delta document defined as sequence of segments.
28+
* Delta document defined as a sequence of segments.
2729
*
28-
* @version 0.1.1 2016/11/05
30+
* @version 0.1.2 2016/12/07
2931
* @author ExBin Project (http://exbin.org)
3032
*/
3133
public class DeltaDocument implements EditableBinaryData {
@@ -35,20 +37,23 @@ public class DeltaDocument implements EditableBinaryData {
3537
private final DefaultDoublyLinkedList<DataSegment> segments = new DefaultDoublyLinkedList<>();
3638

3739
private long dataLength = 0;
38-
private final DeltaDocumentWindow window = new DeltaDocumentWindow(this);
40+
private final DeltaDocumentWindow window;
41+
private final List<DeltaDocumentChangedListener> changeListeners = new ArrayList<>();
3942

4043
public DeltaDocument(SegmentsRepository repository, FileDataSource fileSource) throws IOException {
4144
this.repository = repository;
4245
this.fileSource = fileSource;
4346
dataLength = fileSource.getFileLength();
4447
DataSegment fullFileSegment = repository.createFileSegment(fileSource, 0, dataLength);
4548
segments.add(fullFileSegment);
49+
window = new DeltaDocumentWindow(this);
4650
window.reset();
4751
}
4852

4953
public DeltaDocument(SegmentsRepository repository) {
5054
this.repository = repository;
5155
dataLength = 0;
56+
window = new DeltaDocumentWindow(this);
5257
window.reset();
5358
}
5459

@@ -269,4 +274,18 @@ public void setFileSource(FileDataSource fileSource) {
269274
public SegmentsRepository getRepository() {
270275
return repository;
271276
}
277+
278+
public void addChangeListener(DeltaDocumentChangedListener listener) {
279+
changeListeners.add(listener);
280+
}
281+
282+
public void removeChangeListener(DeltaDocumentChangedListener listener) {
283+
changeListeners.remove(listener);
284+
}
285+
286+
public void notifyChangeListeners(DeltaDocumentWindow window) {
287+
for (DeltaDocumentChangedListener listener : changeListeners) {
288+
listener.dataChanged(window);
289+
}
290+
}
272291
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) ExBin Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.exbin.deltahex.delta;
17+
18+
/**
19+
* Listener for delta document data changes.
20+
*
21+
* @version 0.1.2 2016/12/07
22+
* @author ExBin Project (http://exbin.org)
23+
*/
24+
public interface DeltaDocumentChangedListener {
25+
26+
/**
27+
* Change in data occured.
28+
*
29+
* @param window updated window for reference
30+
*/
31+
void dataChanged(DeltaDocumentWindow window);
32+
}

modules/deltahex-delta/src/main/java/org/exbin/deltahex/delta/DeltaDocumentWindow.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
/**
2323
* Access window for delta document.
2424
*
25-
* @version 0.1.1 2016/11/22
25+
* @version 0.1.2 2016/12/07
2626
* @author ExBin Project (http://exbin.org)
2727
*/
2828
public class DeltaDocumentWindow {
@@ -33,6 +33,15 @@ public class DeltaDocumentWindow {
3333

3434
public DeltaDocumentWindow(DeltaDocument document) {
3535
this.document = document;
36+
document.addChangeListener(new DeltaDocumentChangedListener() {
37+
@Override
38+
public void dataChanged(DeltaDocumentWindow window) {
39+
if (window != DeltaDocumentWindow.this) {
40+
pointer.segment = window.pointer.segment;
41+
pointer.position = window.pointer.position;
42+
}
43+
}
44+
});
3645
}
3746

3847
public long getDataSize() {
@@ -73,6 +82,8 @@ public void setByte(long position, byte value) {
7382
if (documentSegment.getLength() == 1) {
7483
segments.remove(documentSegment);
7584
repository.dropSegment(documentSegment);
85+
pointer.position = 0;
86+
pointer.segment = null;
7687
} else {
7788
repository.updateSegment(documentSegment, documentSegment.getStartPosition() + 1, documentSegment.getLength() - 1);
7889
}
@@ -87,6 +98,7 @@ public void setByte(long position, byte value) {
8798
if (position >= getDataSize()) {
8899
document.setDataLength(position + 1);
89100
}
101+
document.notifyChangeListeners(this);
90102
}
91103

92104
public void insertUninitialized(long startFrom, long length) {
@@ -116,6 +128,7 @@ public void insertUninitialized(long startFrom, long length) {
116128
pointer.segment = insertedSegment;
117129
}
118130
document.setDataLength(targetLength);
131+
document.notifyChangeListeners(this);
119132
}
120133

121134
public void insert(long startFrom, long length) {
@@ -144,6 +157,7 @@ public void insert(long startFrom, long length) {
144157
pointer.segment = insertedSegment;
145158
}
146159
document.setDataLength(targetLength);
160+
document.notifyChangeListeners(this);
147161
}
148162

149163
public void insert(long startFrom, byte[] insertedData) {
@@ -172,6 +186,7 @@ public void insert(long startFrom, byte[] insertedData) {
172186
pointer.segment = insertedSegment;
173187
}
174188
document.setDataLength(targetLength);
189+
document.notifyChangeListeners(this);
175190
}
176191

177192
public void insert(long startFrom, byte[] insertedData, int insertedDataOffset, int insertedDataLength) {
@@ -197,6 +212,7 @@ public void insert(long startFrom, byte[] insertedData, int insertedDataOffset,
197212
pointer.segment = insertedSegment;
198213
}
199214
document.setDataLength(targetLength);
215+
document.notifyChangeListeners(this);
200216
}
201217

202218
public void insert(long startFrom, BinaryData insertedData) {
@@ -251,6 +267,7 @@ public void insert(long startFrom, BinaryData insertedData) {
251267
pointer.segment = insertedSegment;
252268
}
253269
document.setDataLength(targetLength);
270+
document.notifyChangeListeners(this);
254271
}
255272

256273
public void insert(long startFrom, BinaryData insertedData, long insertedDataOffset, long insertedDataLength) {
@@ -310,6 +327,7 @@ public void insert(long startFrom, BinaryData insertedData, long insertedDataOff
310327
pointer.segment = insertedSegment;
311328
}
312329
document.setDataLength(targetLength);
330+
document.notifyChangeListeners(this);
313331
}
314332

315333
public void insert(long startFrom, DataSegment insertedSegment) {
@@ -327,6 +345,7 @@ public void insert(long startFrom, DataSegment insertedSegment) {
327345
}
328346
pointer.segment = insertedSegment;
329347
document.setDataLength(targetLength);
348+
document.notifyChangeListeners(this);
330349
}
331350

332351
public void remove(long startFrom, long length) {
@@ -363,6 +382,7 @@ public void remove(long startFrom, long length) {
363382
tryMergeSegments(startFrom);
364383
document.setDataLength(targetLength);
365384
}
385+
document.notifyChangeListeners(this);
366386
}
367387

368388
public void reset() {

modules/deltahex-delta/src/main/java/org/exbin/deltahex/delta/SegmentsRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ record = null;
287287
}
288288
long overlapPosition = saveMap.get(firstRecord.dataSegment);
289289
preloadSegmentSection(firstRecord.dataSegment, overlapStart, overlapLength, fileSource, saveMap, savedDocument);
290+
// TODO: Replace recursion with iteration
290291
saveSegmentSection(overlapPosition + overlapStart, overlapLength, fileSource, saveMap, savedDocument);
291292
}
292293
}

modules/deltahex-delta/src/test/java/org/exbin/deltahex/delta/DeltaDocumentSaveTest.java

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
/**
3030
* Tests for delta document.
3131
*
32-
* @version 0.1.1 2016/12/06
32+
* @version 0.1.2 2016/12/07
3333
* @author ExBin Project (http://exbin.org)
3434
*/
3535
public class DeltaDocumentSaveTest {
@@ -46,8 +46,11 @@ public class DeltaDocumentSaveTest {
4646
public static final String SAMPLE_REMOVED_MIDDLE = SAMPLE_FILES_PATH + "removed_middle.dat";
4747
public static final String SAMPLE_REMOVED_END = SAMPLE_FILES_PATH + "removed_end.dat";
4848
public static final String SAMPLE_SWAP_HALF = SAMPLE_FILES_PATH + "swaped_half.dat";
49+
public static final String SAMPLE_SWAP_MIDDLE = SAMPLE_FILES_PATH + "swaped_middle.dat";
50+
public static final String SAMPLE_SWAP_DOUBLE = SAMPLE_FILES_PATH + "swaped_double.dat";
4951
public static final String SAMPLE_SWAP_FIRST_QUARTER = SAMPLE_FILES_PATH + "swaped_first_quarter.dat";
5052
public static final String SAMPLE_SWAP_LAST_QUARTER = SAMPLE_FILES_PATH + "swaped_last_quarter.dat";
53+
public static final String SAMPLE_REVERSE = SAMPLE_FILES_PATH + "reversed.dat";
5154
public static final int SAMPLE_ALLBYTES_SIZE = 256;
5255

5356
public DeltaDocumentSaveTest() {
@@ -323,6 +326,66 @@ public void testSwapHalfSaveDocument() {
323326
closeTempDeltaDocument(document);
324327
}
325328

329+
@Test
330+
public void testSwapMiddleSaveDocument() {
331+
DeltaDocument document = openTempDeltaDocument();
332+
assertEquals(SAMPLE_ALLBYTES_SIZE, document.getDataSize());
333+
EditableBinaryData quarterCopy = (EditableBinaryData) document.copy(64, 64);
334+
document.remove(64, 64);
335+
document.insert(128, quarterCopy);
336+
quarterCopy.clear();
337+
338+
try {
339+
document.save();
340+
341+
InputStream comparisionFile;
342+
try (InputStream dataInputStream = document.getDataInputStream()) {
343+
comparisionFile = new FileInputStream(DeltaDocumentSaveTest.class.getResource(SAMPLE_SWAP_MIDDLE).getFile());
344+
TestUtils.assertEqualsInputStream(comparisionFile, dataInputStream);
345+
}
346+
comparisionFile.close();
347+
} catch (IOException ex) {
348+
Logger.getLogger(DeltaDocumentSaveTest.class.getName()).log(Level.SEVERE, null, ex);
349+
fail("Exception: " + ex.getMessage());
350+
}
351+
352+
document.clear();
353+
assertEquals(0, document.getSegments().size());
354+
closeTempDeltaDocument(document);
355+
}
356+
357+
@Test
358+
public void testSwapDoubleSaveDocument() {
359+
DeltaDocument document = openTempDeltaDocument();
360+
assertEquals(SAMPLE_ALLBYTES_SIZE, document.getDataSize());
361+
EditableBinaryData quarterCopy = (EditableBinaryData) document.copy(0, 64);
362+
document.remove(0, 64);
363+
document.insert(64, quarterCopy);
364+
quarterCopy.clear();
365+
EditableBinaryData quarterCopy2 = (EditableBinaryData) document.copy(128, 64);
366+
document.remove(128, 64);
367+
document.insert(192, quarterCopy2);
368+
quarterCopy2.clear();
369+
370+
try {
371+
document.save();
372+
373+
InputStream comparisionFile;
374+
try (InputStream dataInputStream = document.getDataInputStream()) {
375+
comparisionFile = new FileInputStream(DeltaDocumentSaveTest.class.getResource(SAMPLE_SWAP_DOUBLE).getFile());
376+
TestUtils.assertEqualsInputStream(comparisionFile, dataInputStream);
377+
}
378+
comparisionFile.close();
379+
} catch (IOException ex) {
380+
Logger.getLogger(DeltaDocumentSaveTest.class.getName()).log(Level.SEVERE, null, ex);
381+
fail("Exception: " + ex.getMessage());
382+
}
383+
384+
document.clear();
385+
assertEquals(0, document.getSegments().size());
386+
closeTempDeltaDocument(document);
387+
}
388+
326389
@Test
327390
public void testSwapFirstQuarterSaveDocument() {
328391
DeltaDocument document = openTempDeltaDocument();
@@ -379,6 +442,64 @@ public void testSwapLastQuarterSaveDocument() {
379442
closeTempDeltaDocument(document);
380443
}
381444

445+
@Test
446+
public void testReverseSaveDocument() {
447+
DeltaDocument document = openTempDeltaDocument();
448+
assertEquals(SAMPLE_ALLBYTES_SIZE, document.getDataSize());
449+
for (int i = 0; i < 128; i++) {
450+
byte buf = document.getByte(i);
451+
document.setByte(i, document.getByte(255 - i));
452+
document.setByte(255 - i, buf);
453+
}
454+
455+
try {
456+
document.save();
457+
458+
InputStream comparisionFile;
459+
try (InputStream dataInputStream = document.getDataInputStream()) {
460+
comparisionFile = new FileInputStream(DeltaDocumentSaveTest.class.getResource(SAMPLE_REVERSE).getFile());
461+
TestUtils.assertEqualsInputStream(comparisionFile, dataInputStream);
462+
}
463+
comparisionFile.close();
464+
} catch (IOException ex) {
465+
Logger.getLogger(DeltaDocumentSaveTest.class.getName()).log(Level.SEVERE, null, ex);
466+
fail("Exception: " + ex.getMessage());
467+
}
468+
469+
document.clear();
470+
assertEquals(0, document.getSegments().size());
471+
closeTempDeltaDocument(document);
472+
}
473+
474+
@Test
475+
public void testSwapReverseSaveDocument() {
476+
DeltaDocument document = openTempDeltaDocument();
477+
assertEquals(SAMPLE_ALLBYTES_SIZE, document.getDataSize());
478+
for (int i = 0; i < 128; i++) {
479+
byte buf = document.getByte(i);
480+
document.setByte(i, document.getByte(255 - i));
481+
document.setByte(255 -i, buf);
482+
}
483+
484+
try {
485+
document.save();
486+
487+
InputStream comparisionFile;
488+
try (InputStream dataInputStream = document.getDataInputStream()) {
489+
comparisionFile = new FileInputStream(DeltaDocumentSaveTest.class.getResource(SAMPLE_REVERSE).getFile());
490+
TestUtils.assertEqualsInputStream(comparisionFile, dataInputStream);
491+
}
492+
comparisionFile.close();
493+
} catch (IOException ex) {
494+
Logger.getLogger(DeltaDocumentSaveTest.class.getName()).log(Level.SEVERE, null, ex);
495+
fail("Exception: " + ex.getMessage());
496+
}
497+
498+
document.clear();
499+
assertEquals(0, document.getSegments().size());
500+
closeTempDeltaDocument(document);
501+
}
502+
382503
public static DeltaDocument openTempDeltaDocument() {
383504
SegmentsRepository segmentsRepository = new SegmentsRepository();
384505

Binary file not shown.
Binary file not shown.
Binary file not shown.

modules/deltahex-java-modules.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ buildscript {
2323
mavenLocal()
2424
jcenter()
2525
}
26-
dependencies {
27-
classpath("at.bxm.gradleplugins:gradle-svntools-plugin:latest.integration")
28-
}
26+
// dependencies {
27+
// classpath("at.bxm.gradleplugins:gradle-svntools-plugin:latest.integration")
28+
// }
2929
}
3030

31-
['java', 'maven', 'maven-publish', 'at.bxm.svntools', 'signing'].each {
31+
['java', 'maven', 'maven-publish', 'signing'].each { // 'at.bxm.svntools'
3232
apply plugin: it
3333
}
3434

0 commit comments

Comments
 (0)