3333/**
3434 * Repository of delta segments.
3535 *
36- * @version 0.1.1 2016/12/01
36+ * @version 0.1.2 2016/12/12
3737 * @author ExBin Project (http://exbin.org)
3838 */
3939public class SegmentsRepository {
@@ -586,9 +586,7 @@ public void dropDocument(DeltaDocument document) {
586586 public void setMemoryByte (MemorySegment memorySegment , long segmentPosition , byte value ) {
587587 MemoryDataSource memorySource = memorySegment .getSource ();
588588 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
589- if (segmentsMap .hasMoreSegments ()) {
590- throw new UnsupportedOperationException ("Not supported yet." );
591- }
589+ detachMemoryArea (memorySegment , memorySegment .getStartPosition () + segmentPosition , 1 );
592590
593591 if (segmentPosition >= memorySegment .getLength ()) {
594592 segmentsMap .updateSegmentLength (memorySegment , segmentPosition + 1 );
@@ -602,47 +600,53 @@ public void setMemoryByte(MemorySegment memorySegment, long segmentPosition, byt
602600 public void insertMemoryData (MemorySegment memorySegment , long position , BinaryData insertedData ) {
603601 MemoryDataSource memorySource = memorySegment .getSource ();
604602 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
605- detachMemoryArea (memorySegment , position , insertedData .getDataSize ());
603+ detachMemoryArea (memorySegment , position , 0 );
604+ shiftSegments (memorySegment , position , insertedData .getDataSize ());
606605 memorySegment .getSource ().insert (position , insertedData );
607606 segmentsMap .updateSegmentLength (memorySegment , memorySegment .getLength () + insertedData .getDataSize ());
608607 }
609608
610609 public void insertMemoryData (MemorySegment memorySegment , long position , BinaryData insertedData , long insertedDataOffset , long insertedDataLength ) {
611610 MemoryDataSource memorySource = memorySegment .getSource ();
612611 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
613- detachMemoryArea (memorySegment , position , insertedData .getDataSize ());
612+ detachMemoryArea (memorySegment , position , 0 );
613+ shiftSegments (memorySegment , position , insertedDataLength );
614614 memorySegment .getSource ().insert (position , insertedData , insertedDataOffset , insertedDataLength );
615615 segmentsMap .updateSegmentLength (memorySegment , memorySegment .getLength () + insertedDataLength );
616616 }
617617
618618 public void insertMemoryData (MemorySegment memorySegment , long position , byte [] insertedData ) {
619619 MemoryDataSource memorySource = memorySegment .getSource ();
620620 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
621- detachMemoryArea (memorySegment , position , insertedData .length );
621+ detachMemoryArea (memorySegment , position , 0 );
622+ shiftSegments (memorySegment , position , insertedData .length );
622623 memorySegment .getSource ().insert (position , insertedData );
623624 segmentsMap .updateSegmentLength (memorySegment , memorySegment .getLength () + insertedData .length );
624625 }
625626
626627 public void insertMemoryData (MemorySegment memorySegment , long position , byte [] insertedData , int insertedDataOffset , int insertedDataLength ) {
627628 MemoryDataSource memorySource = memorySegment .getSource ();
628629 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
629- detachMemoryArea (memorySegment , position , insertedData .length );
630+ detachMemoryArea (memorySegment , position , 0 );
631+ shiftSegments (memorySegment , position , insertedDataLength );
630632 memorySegment .getSource ().insert (position , insertedData , insertedDataOffset , insertedDataLength );
631633 segmentsMap .updateSegmentLength (memorySegment , memorySegment .getLength () + insertedDataLength );
632634 }
633635
634636 public void insertMemoryData (MemorySegment memorySegment , long position , long length ) {
635637 MemoryDataSource memorySource = memorySegment .getSource ();
636638 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
637- detachMemoryArea (memorySegment , position , length );
639+ detachMemoryArea (memorySegment , position , 0 );
640+ shiftSegments (memorySegment , position , length );
638641 memorySegment .getSource ().insert (position , length );
639642 segmentsMap .updateSegmentLength (memorySegment , memorySegment .getLength () + length );
640643 }
641644
642645 public void insertUninitializedMemoryData (MemorySegment memorySegment , long position , long length ) {
643646 MemoryDataSource memorySource = memorySegment .getSource ();
644647 DataSegmentsMap segmentsMap = memorySources .get (memorySource );
645- detachMemoryArea (memorySegment , position , length );
648+ detachMemoryArea (memorySegment , position , 0 );
649+ shiftSegments (memorySegment , position , length );
646650 memorySegment .getSource ().insertUninitialized (position , length );
647651 segmentsMap .updateSegmentLength (memorySegment , memorySegment .getLength () + length );
648652 }
@@ -657,15 +661,57 @@ public void insertUninitializedMemoryData(MemorySegment memorySegment, long posi
657661 */
658662 public void detachMemoryArea (MemorySegment memorySegment , long position , long length ) {
659663 DataSegmentsMap segmentsMap = memorySources .get (memorySegment .getSource ());
660- // TODO
661- // for (MemorySegment segment : segmentsMap.getAllSegments()) {
662- // if (segment != memorySegment) {
663- // if (position >= segment.getStartPosition() && position < segment.getStartPosition() + segment.getLength()) {
664- // // TODO: If segments collide, copy on write
665- // throw new UnsupportedOperationException("Not supported yet.");
666- // }
667- // }
668- // }
664+ if (!segmentsMap .hasMoreSegments ()) {
665+ return ;
666+ }
667+
668+ SegmentRecord record = segmentsMap .focusFirstOverlay (position , length );
669+ while (record != null ) {
670+ if (record .getStartPosition () > position + length ) {
671+ break ;
672+ }
673+ if (record .getStartPosition () + record .getLength () > position ) {
674+ DataSegment segment = record .dataSegment ;
675+ record = record .getNext ();
676+ detachSegment ((MemorySegment ) segment );
677+ } else {
678+ record = record .getNext ();
679+ }
680+ }
681+ }
682+
683+ public void detachSegment (MemorySegment memorySegment ) {
684+ MemoryDataSource source = memorySegment .getSource ();
685+ MemoryDataSource newMemorySource = openMemorySource ();
686+ newMemorySource .insert (0 , source .copy (memorySegment .getStartPosition (), memorySegment .getLength ()));
687+ DataSegmentsMap segmentsMap = memorySources .get (source );
688+ segmentsMap .remove (memorySegment );
689+ memorySegment .setSource (newMemorySource );
690+ DataSegmentsMap newSegmentsMap = memorySources .get (newMemorySource );
691+ newSegmentsMap .add (memorySegment );
692+ }
693+
694+ /**
695+ * Shift all segments after given position in given direction.
696+ *
697+ * Operation assumes there are no collisions.
698+ *
699+ * @param memorySegment memory segment to keep
700+ * @param position position of the shift
701+ * @param shift direction of the shift
702+ */
703+ public void shiftSegments (MemorySegment memorySegment , long position , long shift ) {
704+ MemoryDataSource source = memorySegment .getSource ();
705+ DataSegmentsMap segmentsMap = memorySources .get (memorySegment .getSource ());
706+ SegmentRecord record = segmentsMap .focusFirstOverlay (position , source .getDataSize () - position );
707+ while (record != null ) {
708+ if (record .getStartPosition () >= position ) {
709+ MemorySegment segment = (MemorySegment ) record .dataSegment ;
710+ segment .setStartPosition (segment .getStartPosition () + shift );
711+ record .maxPosition += shift ;
712+ }
713+ record = record .getNext ();
714+ }
669715 }
670716
671717 /**
0 commit comments