2e460d66cd0115d56c543e0df91c712e1eee490e
[IRC.git] / Robust / Transactions / TransactionalIO / src / TransactionalIO / core / TransactionalFile.java
1 /*
2  * To change this template, choose Tools | Templates
3  * and open the template in the editor.
4  */
5 package TransactionalIO.core;
6
7 import TransactionalIO.Utilities.Range;
8 import TransactionalIO.exceptions.AbortedException;
9 import TransactionalIO.exceptions.PanicException;
10 import TransactionalIO.benchmarks.benchmark;
11 import TransactionalIO.core.ExtendedTransaction.Status;
12 import TransactionalIO.interfaces.BlockAccessModesEnum;
13 import TransactionalIO.interfaces.OffsetDependency;
14 import com.sun.org.apache.bcel.internal.generic.IFEQ;
15 import java.io.File;
16 import java.io.FileDescriptor;
17 import java.io.FileNotFoundException;
18 import java.io.IOException;
19 import java.io.RandomAccessFile;
20 import java.nio.ByteBuffer;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.TreeMap;
24 import java.util.Vector;
25 import java.util.concurrent.locks.Lock;
26 import java.util.concurrent.locks.ReentrantLock;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29
30 /**
31  *
32  * @author navid
33  */
34 public class TransactionalFile implements Comparable {
35
36     private native int nativepread(byte buff[], long offset, int size, FileDescriptor fd);
37     private native int nativepwrite(byte buff[], long offset, int size, FileDescriptor fd);
38     
39
40     {
41         System.load("/home/navid/libkooni.so");
42     }
43     public RandomAccessFile file;
44     private INode inode;
45     private int sequenceNum = 0;
46     public static int currenSeqNumforInode = 0;
47     /*  public AtomicLong commitedoffset;
48     public AtomicLong commitedfilesize;*/
49     public boolean to_be_created = false;
50     public boolean writemode = false;
51     public boolean appendmode = false;
52     public ReentrantLock offsetlock;
53     private GlobalOffset committedoffset;
54     private GlobalINodeState inodestate;
55
56     public TransactionalFile(String filename, String mode) {
57
58
59         File f = new File(filename);
60
61         if ((!(f.exists()))) {
62             to_be_created = true;
63             file = null;
64
65         } else {
66
67             try {
68
69                 offsetlock = new ReentrantLock();
70                 file = new RandomAccessFile(f, mode);
71             } catch (FileNotFoundException ex) {
72
73                 Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
74             }
75
76         }
77         inode = TransactionalFileWrapperFactory.getINodefromFileName(filename);
78         inodestate = TransactionalFileWrapperFactory.createTransactionalFile(inode, filename, mode);
79
80
81         sequenceNum = inodestate.seqNum;
82         inodestate.seqNum++;
83
84         if (mode.equals("rw")) {
85             writemode = true;
86         } else if (mode.equals("a")) {
87             appendmode = true;
88         }
89
90         if (inodestate != null) {
91             synchronized (inodestate) {
92                 committedoffset = new GlobalOffset(0);
93             }
94         }
95
96
97     }
98
99     private int invokeNativepread(byte buff[], long offset, int size) {
100         try {
101             return nativepread(buff, offset, size, file.getFD());
102         } catch (IOException ex) {
103
104             Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
105             return -1;
106         }
107
108     }
109       public int invokeNativepwrite(byte buff[], long offset, int size, RandomAccessFile file) {
110         try {
111             return nativepwrite(buff, offset, buff.length, file.getFD());
112         } catch (IOException ex) {
113
114             Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
115             return -1;
116         }
117
118     }
119
120     public int getSequenceNum() {
121         return sequenceNum;
122     }
123
124     public GlobalOffset getCommitedoffset() {
125         return committedoffset;
126     }
127
128     public GlobalINodeState getInodestate() {
129         return inodestate;
130     }
131
132     public INode getInode() {
133         return inode;
134     }
135
136     public void close() {
137         try {
138             file.close();
139         } catch (IOException ex) {
140             Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
141         }
142     }
143
144     public long getFilePointer() {
145
146         ExtendedTransaction me = Wrapper.getTransaction();
147         TransactionLocalFileAttributes tmp = null;
148
149         if (me == null) {
150             return non_Transactional_getFilePointer();
151         }
152
153         if (!(me.getGlobaltoLocalMappings().containsKey(this))) {
154             me.addFile(this, 0);
155         }
156
157         tmp = (TransactionLocalFileAttributes) me.getGlobaltoLocalMappings().get(this);
158         if ((tmp.getOffsetdependency() == OffsetDependency.WRITE_DEPENDENCY_1) || (tmp.getOffsetdependency() == OffsetDependency.NO_ACCESS)) {
159             tmp.setOffsetdependency(OffsetDependency.READ_DEPENDENCY);
160
161             long target;
162             lockOffset(me);
163
164             if (!(this.committedoffset.getOffsetReaders().contains(me))) {
165                 this.committedoffset.getOffsetReaders().add(me);
166
167             }
168
169             tmp.setLocaloffset(tmp.getLocaloffset() + this.committedoffset.getOffsetnumber() - tmp.getCopylocaloffset());
170             target = this.committedoffset.getOffsetnumber() - tmp.getCopylocaloffset();
171
172
173             offsetlock.unlock();
174             Iterator it;
175
176             if ((me.getWriteBuffer().get(inode)) != null) {
177
178                 it = ((Vector) (me.getWriteBuffer().get(inode))).iterator();
179                 while (it.hasNext()) {
180                     WriteOperations wrp = (WriteOperations) it.next();
181                     if (wrp.getBelongingto() == tmp && wrp.isUnknownoffset()) {
182                         wrp.setUnknownoffset(false);
183                     }
184                     wrp.getRange().setStart(target + wrp.getRange().getStart());
185                     wrp.getRange().setEnd(target + wrp.getRange().getEnd());
186                 }
187             }
188
189         }
190
191
192         tmp.setUnknown_inital_offset_for_write(false);
193         return tmp.getLocaloffset();
194     }
195
196     public void seek(long offset) {
197
198         ExtendedTransaction me = Wrapper.getTransaction();
199
200         if (me == null) {
201             non_Transactional_Seek(offset);
202             return;
203         } else {
204             TransactionLocalFileAttributes tmp = null;
205             if (!(me.getGlobaltoLocalMappings().containsKey(this))) {
206                 me.addFile(this, offset);
207             }
208             tmp = (TransactionLocalFileAttributes) me.getGlobaltoLocalMappings().get(this);
209
210             if (tmp.getOffsetdependency() == OffsetDependency.NO_ACCESS) {
211                 tmp.setOffsetdependency(OffsetDependency.NO_DEPENDENCY);
212             } else if (tmp.getOffsetdependency() == OffsetDependency.WRITE_DEPENDENCY_1) {
213                 tmp.setOffsetdependency(OffsetDependency.WRITE_DEPENDENCY_2);
214             }
215             tmp.setUnknown_inital_offset_for_write(false);
216             tmp.setLocaloffset(offset);
217         }
218     }
219
220     public int read(byte[] b) {
221
222
223         ExtendedTransaction me = Wrapper.getTransaction();
224         int size = b.length;
225         int result = 0;
226         if (me == null) {  // not a transaction, but any I/O operation even though within a non-transaction is considered a single opertion transactiion 
227
228             return non_Transactional_Read(b);
229         }
230         if (!(me.getGlobaltoLocalMappings().containsKey(this))) {
231             me.addFile(this, 0);
232         }
233         
234         if (me.getGlobaltoLocalMappings().containsKey(this)) {
235
236             TransactionLocalFileAttributes tmp = (TransactionLocalFileAttributes) me.getGlobaltoLocalMappings().get(this);
237             tmp.setUnknown_inital_offset_for_write(false);
238
239             OffsetDependency dep = tmp.getOffsetdependency();
240             if ((dep == OffsetDependency.WRITE_DEPENDENCY_1) ||
241                     (dep == OffsetDependency.NO_ACCESS) ||
242                     (dep == OffsetDependency.WRITE_DEPENDENCY_2)) {
243                 tmp.setOffsetdependency(OffsetDependency.READ_DEPENDENCY);
244                 lockOffset(me);
245
246                 if (dep != OffsetDependency.WRITE_DEPENDENCY_2) {
247                     tmp.setLocaloffset(tmp.getLocaloffset() + this.committedoffset.getOffsetnumber() - tmp.getCopylocaloffset());
248                 }
249
250                 if (!(this.committedoffset.getOffsetReaders().contains(me))) {
251                     this.committedoffset.getOffsetReaders().add(me);
252
253                 }
254
255                 offsetlock.unlock();
256             }
257
258
259             makeWritestDependent(me);
260
261
262             if ((Boolean) me.merge_for_writes_done.get(inode) == Boolean.FALSE) {
263                 mergeWrittenData(me);
264             }
265
266             long loffset = tmp.getLocaloffset();
267             markAccessedBlocks(me, loffset, size, BlockAccessModesEnum.READ);
268
269
270             Vector writebuffer;
271             if ((me.getWriteBuffer().get(this.inode)) != null) {
272                 writebuffer = (Vector) (me.getWriteBuffer().get(this.inode));
273             } else {
274                 writebuffer = new Vector();
275                 me.getWriteBuffer().put(this.inode, writebuffer);
276             }
277             Range readrange = new Range(loffset, loffset + size);
278             Range writerange = null;
279             Range[] intersectedrange = new Range[writebuffer.size()];
280             WriteOperations[] markedwriteop = new WriteOperations[writebuffer.size()];
281
282             int counter = 0;
283             boolean in_local_buffer = false;
284
285
286             Iterator it = writebuffer.iterator();
287             while (it.hasNext()) {
288
289                 WriteOperations wrp = (WriteOperations) it.next();
290                 writerange = wrp.getRange();
291                 if (writerange.includes(readrange)) {
292                     markedwriteop[counter] = wrp;
293                     in_local_buffer = true;
294                     break;
295                 }
296
297                 if (writerange.hasIntersection(readrange)) {
298                     intersectedrange[counter] = readrange.intersection(writerange);
299                     markedwriteop[counter] = wrp;
300
301                     counter++;
302                 }
303             }
304
305             if (in_local_buffer) { // the read one from local buffer
306
307                 result = readFromBuffer(b, tmp, markedwriteop[counter], writerange);
308                 return result;
309                 
310             } else {
311
312                 if (counter == 0) { // all the read straight from file
313
314                     result = readFromFile(me, b, tmp);
315                 } else {    // some parts from file others from buffer
316
317                     for (int i = 0; i < counter; i++) {
318                         Byte[] data = markedwriteop[i].getData();
319                         byte[] copydata = new byte[data.length];
320                         for (int j = 0; j < data.length; j++) {
321                             copydata[j] = data[j].byteValue();
322                         }
323                         System.arraycopy(copydata, (int) (intersectedrange[i].getStart() - markedwriteop[i].getRange().getStart()), b, (int) (intersectedrange[i].getStart() - readrange.getStart()), (int) (Math.min(intersectedrange[i].getEnd(), readrange.getEnd()) - intersectedrange[i].getStart()));
324                         result += Math.min(intersectedrange[i].getEnd(), readrange.getEnd()) - intersectedrange[i].getStart();
325                     }
326
327                     Range[] non_intersected_ranges = readrange.minus(intersectedrange, counter);
328                     Vector occupiedblocks = new Vector();
329                     for (int i = 0; i < non_intersected_ranges.length; i++) {
330                         int st = FileBlockManager.getCurrentFragmentIndexofTheFile(non_intersected_ranges[i].getStart());
331                         int en = FileBlockManager.getCurrentFragmentIndexofTheFile(non_intersected_ranges[i].getEnd());
332                         for (int j = st; j <= en; j++) {
333                             if (!(occupiedblocks.contains(Integer.valueOf(j)))) {
334                                 occupiedblocks.add(Integer.valueOf(j));
335                             }
336                         }
337                     }
338
339                   //  lockOffset(me);
340                     
341                     me.getHeldoffsetlocks().add(offsetlock);
342                     boolean locked = false;
343                     BlockDataStructure block;
344                     for (int k = 0; k < occupiedblocks.size(); k++) {   // locking the block locks
345
346                         while (me.getStatus() == Status.ACTIVE) {
347                             block = this.inodestate.getBlockDataStructure((Integer) (occupiedblocks.get(k)));//(BlockDataStructure) tmp.adapter.lockmap.get(Integer.valueOf(k)));
348
349                             block.getLock().readLock().lock();
350                             if (!(block.getReaders().contains(me))) {
351                                 block.getReaders().add(me);
352                             }
353                             locked = true;
354                             //me.getHeldblocklocks().add(block.getLock().readLock());
355                             break;
356                         }
357                         if (me.getStatus() == Status.ABORTED) {
358                             int m;
359                             if (locked) {
360                                 m = k + 1;
361                             } else {
362                                 m = k;
363                             }
364                             for (int i = 0; i < m; i++) {
365                                 block = this.inodestate.getBlockDataStructure((Integer) (occupiedblocks.get(k)));
366                                 me.getHeldblocklocks().add(block.getLock().readLock());
367                             }
368
369                             locked = false;
370                             throw new AbortedException();
371                         }
372                     }
373
374                     for (int i = 0; i < non_intersected_ranges.length; i++) {
375                      //   try {
376                             int sizetoread = (int) (non_intersected_ranges[i].getEnd() - non_intersected_ranges[i].getStart());
377                             byte[] tmpdt =  new byte[(int) (non_intersected_ranges[i].getEnd() - non_intersected_ranges[i].getStart())];
378                             int tmpsize = invokeNativepread(tmpdt, non_intersected_ranges[i].getStart(), sizetoread);
379                             System.arraycopy(tmpdt, 0, b, (int) (non_intersected_ranges[i].getStart() - readrange.getStart()), sizetoread);
380                             //file.seek(non_intersected_ranges[i].getStart());
381                             //int tmpsize = file.read(b, (int) (non_intersected_ranges[i].getStart() - readrange.getStart()), (int) (non_intersected_ranges[i].getEnd() - non_intersected_ranges[i].getStart()));
382                             result += tmpsize;
383                       //  } catch (IOException ex) {
384                         //    Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
385                        // }
386                     }
387
388                     if (me.getStatus() == Status.ABORTED) {
389                         for (int k = 0; k < occupiedblocks.size(); k++) {
390                             block = this.inodestate.getBlockDataStructure((Integer) (occupiedblocks.get(k)));
391                             me.getHeldblocklocks().add(block.getLock().readLock());
392                         }
393                         throw new AbortedException();
394                     }
395                     for (int k = 0; k < occupiedblocks.size(); k++) {
396                         block = this.inodestate.getBlockDataStructure((Integer) (occupiedblocks.get(k)));//(BlockDataStructure) tmp.adapter.lockmap.get(Integer.valueOf(k)));
397
398                         block.getLock().readLock().unlock();
399                     }
400                    // offsetlock.unlock();
401                     tmp.setLocaloffset(tmp.getLocaloffset() + result);
402                 }
403
404                 return result;
405             }
406
407         } else {           // add to the readers list 
408          //   me.addFile(this, 0);
409             return read(b);
410         }
411
412     }
413
414     public void write(byte[] data) throws IOException {
415
416         if (!(writemode)) {
417             throw new IOException();
418
419         }
420
421         ExtendedTransaction me = Wrapper.getTransaction();
422         int size = data.length;
423
424
425         if (me == null) // not a transaction 
426         {
427
428             non_Transactional_Write(data);
429             return;
430         }
431
432         if (me.getGlobaltoLocalMappings().containsKey(this)) // 
433         {
434
435
436             Byte[] by = new Byte[size];
437             for (int i = 0; i < size; i++) {
438                 by[i] = Byte.valueOf(data[i]);
439             }
440             TransactionLocalFileAttributes tmp = ((TransactionLocalFileAttributes) (me.getGlobaltoLocalMappings().get(this)));
441
442             Vector dummy;
443             if (((Vector) (me.getWriteBuffer().get(this.inode))) != null) {
444                 dummy = new Vector((Vector) (me.getWriteBuffer().get(this.inode)));
445             } else {
446                 dummy = new Vector();
447             }
448             dummy.add(new WriteOperations(by, new Range(tmp.getLocaloffset(), tmp.getLocaloffset() + by.length), tmp.isUnknown_inital_offset_for_write(), this, tmp));
449             me.getWriteBuffer().put(this.inode, dummy);
450
451             long loffset = tmp.getLocaloffset();
452
453
454             tmp.setLocaloffset(tmp.getLocaloffset() + by.length);
455
456             me.merge_for_writes_done.put(inode, Boolean.FALSE);
457
458             if (!(tmp.isUnknown_inital_offset_for_write())) {
459                 markAccessedBlocks(me, loffset, size, BlockAccessModesEnum.WRITE);
460
461             }
462             if (tmp.getOffsetdependency() == OffsetDependency.NO_ACCESS) {
463                 tmp.offsetdependency = OffsetDependency.WRITE_DEPENDENCY_1;
464             }
465         } else {
466             me.addFile(this, 0);
467             write(data);
468         }
469     }
470
471     private void markAccessedBlocks(ExtendedTransaction me, long loffset, int size, BlockAccessModesEnum mode) {
472
473         TreeMap map;
474
475         if (me.getAccessedBlocks().get(this.getInode()) != null) {
476             map = (TreeMap) me.getAccessedBlocks().get(this.getInode());
477         } else {
478             map = new TreeMap();
479             me.getAccessedBlocks().put(this.inode, map);
480         }
481         int startblock = FileBlockManager.getCurrentFragmentIndexofTheFile(loffset);
482         int targetblock = FileBlockManager.getTargetFragmentIndexofTheFile(loffset, size);
483         for (int i = startblock; i <= targetblock; i++) {
484             if (map.containsKey(Integer.valueOf(i))) {
485                 if (map.get(Integer.valueOf(i)) != mode) {
486                     map.put(Integer.valueOf(i), BlockAccessModesEnum.READ_WRITE);
487                 }
488             } else {
489                 map.put(Integer.valueOf(i), mode);
490             }
491         }
492     }
493
494     private int readFromFile(ExtendedTransaction me, byte[] readdata, TransactionLocalFileAttributes tmp) {
495
496         int st = FileBlockManager.getCurrentFragmentIndexofTheFile(tmp.getLocaloffset());
497         int end = FileBlockManager.getTargetFragmentIndexofTheFile(tmp.getLocaloffset(), readdata.length);
498
499         BlockDataStructure block = null;
500         boolean locked = false;
501         for (int k = st; k <= end; k++) {
502             while (me.getStatus() == Status.ACTIVE) {
503
504                 block = this.inodestate.getBlockDataStructure(Integer.valueOf(k));
505
506                 block.getLock().readLock().lock();
507
508                 if (!(block.getReaders().contains(me))) {
509                     block.getReaders().add(me);
510                 }
511                 locked = true;
512                 break;
513             }
514             if (me.getStatus() == Status.ABORTED) {
515                 int m;
516                 if (locked) {
517                     m = k + 1;
518                 } else {
519                     m = k;
520                 }
521                 for (int i = st; i < m; i++) {
522                     block = this.inodestate.getBlockDataStructure(Integer.valueOf(k));
523                     me.getHeldblocklocks().add(block.getLock().readLock());
524                 }
525                 locked = false;
526                 throw new AbortedException();
527             }
528         }
529
530         int size = -1;
531         size = invokeNativepread(readdata, tmp.getLocaloffset(), readdata.length);
532         tmp.setLocaloffset(tmp.getLocaloffset() + size);
533
534         if (size == 0) {
535             size = -1;
536         }
537         if (me.getStatus() == Status.ABORTED) {
538             for (int i = st; i <= end; i++) {
539                 block = this.inodestate.getBlockDataStructure(Integer.valueOf(i));
540                 me.getHeldblocklocks().add(block.getLock().readLock());
541             }
542             throw new AbortedException();
543         }
544         for (int k = st; k <= end; k++) {
545             block = this.inodestate.getBlockDataStructure(Integer.valueOf(k));
546             block.getLock().readLock().unlock();
547         }
548         return size;
549
550
551     }
552
553     private int readFromBuffer(byte[] readdata, TransactionLocalFileAttributes tmp, WriteOperations wrp, Range writerange) {
554         long loffset = tmp.getLocaloffset();
555
556         Byte[] data = (Byte[]) wrp.getData();
557         byte[] copydata = new byte[data.length];
558
559         for (int i = 0; i < data.length; i++) {
560             copydata[i] = data[i].byteValue();
561         }
562         System.arraycopy(copydata, (int) (loffset - writerange.getStart()), readdata, 0, readdata.length);
563         tmp.setLocaloffset(tmp.getLocaloffset() + readdata.length);
564         return readdata.length;
565
566     }
567
568     public void simpleWritetoBuffer(Byte[] data, Range newwriterange, TreeMap tm) {
569         tm.put(newwriterange, data);
570     }
571
572     public void unlockLocks(Vector heldlocks) {
573         for (int i = 0; i < heldlocks.size(); i++) {
574             ((Lock) heldlocks.get(i)).unlock();
575         }
576     }
577
578     public void setInode(INode inode) {
579         this.inode = inode;
580     }
581
582     public void lockOffset(ExtendedTransaction me) {
583         boolean locked = false;
584         while (me.getStatus() == Status.ACTIVE) {                        //locking the offset
585
586             offsetlock.lock();
587             locked = true;
588             break;
589         }
590
591         if (me.getStatus() != Status.ACTIVE) {
592             if (locked) {
593                 me.getHeldoffsetlocks().add(offsetlock);
594             }
595             throw new AbortedException();
596         }
597
598     }
599
600     public void mergeWrittenData(ExtendedTransaction me/*TreeMap target, byte[] data, Range to_be_merged_data_range*/) {
601
602         boolean flag = false;
603         Vector vec = (Vector) me.getWriteBuffer().get(this.inode);
604         Range intersectedrange = new Range(0, 0);
605         Iterator it1 = vec.iterator();
606         WriteOperations wrp;
607         WriteOperations wrp2;
608         Vector toberemoved = new Vector();
609         while (it1.hasNext()) {
610             wrp = (WriteOperations) (it1.next());
611
612             if (toberemoved.contains(wrp)) {
613                 continue;
614             }
615
616             Iterator it2 = vec.listIterator();
617             while (it2.hasNext()) {
618                 flag = false;
619                 wrp2 = (WriteOperations) (it2.next());
620
621                 if ((wrp2 == wrp) || toberemoved.contains(wrp2)) {
622                     continue;
623                 }
624
625                 if (wrp.getRange().hasIntersection(wrp2.getRange())) {
626                     flag = true;
627                     intersectedrange = wrp2.getRange().intersection(wrp.getRange());
628                     toberemoved.add(wrp2);
629                 }
630
631
632                 long startprefix = 0;
633                 long endsuffix = 0;
634                 long startsuffix = 0;
635                 int prefixsize = 0;
636                 int suffixsize = 0;
637                 int intermediatesize = 0;
638                 Byte[] prefixdata = null;
639                 Byte[] suffixdata = null;
640                 boolean prefix = false;
641                 boolean suffix = false;
642                 if (flag) {
643
644
645                     if (wrp.getRange().getStart() < wrp2.getRange().getStart()) {
646                         prefixdata = new Byte[(int) (wrp2.getRange().getStart() - wrp.getRange().getStart())];
647                         prefixdata = (Byte[]) (wrp.getData());
648                         startprefix = wrp.getRange().getStart();
649                         prefixsize = (int) (intersectedrange.getStart() - startprefix);
650                         intermediatesize = (int) (intersectedrange.getEnd() - intersectedrange.getStart());
651                         prefix = true;
652                     } else if (wrp2.getRange().getStart() <= wrp.getRange().getStart()) {
653                         prefixdata = new Byte[(int) (wrp.getRange().getStart() - wrp2.getRange().getStart())];
654                         prefixdata = (Byte[]) (wrp2.getData());
655                         startprefix = wrp2.getRange().getStart();
656                         prefixsize = (int) (intersectedrange.getStart() - startprefix);
657                         intermediatesize = (int) (intersectedrange.getEnd() - intersectedrange.getStart());
658                         prefix = true;
659                     }
660
661                     if (wrp2.getRange().getEnd() >= wrp.getRange().getEnd()) {
662
663                         suffixdata = new Byte[(int) (wrp2.getRange().getEnd() - intersectedrange.getEnd())];
664                         suffixdata = (Byte[]) (wrp2.getData());
665                         startsuffix = intersectedrange.getEnd() - wrp2.getRange().getStart();
666                         suffixsize = (int) (wrp2.getRange().getEnd() - intersectedrange.getEnd());
667                         suffix = true;
668                         endsuffix = wrp2.getRange().getEnd();
669                     } else if (wrp.getRange().getEnd() > wrp2.getRange().getEnd()) {
670                         suffixdata = new Byte[(int) (wrp.getRange().getEnd() - intersectedrange.getEnd())];
671                         suffixdata = (Byte[]) (wrp.getData());
672                         startsuffix = intersectedrange.getEnd() - wrp.getRange().getStart();
673                         suffixsize = (int) (wrp.getRange().getEnd() - intersectedrange.getEnd());
674                         endsuffix = wrp.getRange().getEnd();
675                         suffix = true;
676
677                     }
678
679                     Byte[] data_to_insert;
680
681                     if ((prefix) && (suffix)) {
682                         data_to_insert = new Byte[(int) (endsuffix - startprefix)];
683                         System.arraycopy(prefixdata, 0, data_to_insert, 0, prefixsize);
684                         System.arraycopy(wrp2.getData(), (int) (intersectedrange.getStart() - wrp2.getRange().getStart()), data_to_insert, prefixsize, intermediatesize);
685                         System.arraycopy(suffixdata, (int) startsuffix, data_to_insert, (prefixsize + intermediatesize), suffixsize);
686                         wrp.setData(data_to_insert);
687                         wrp.setRange(new Range(startprefix, endsuffix));
688                     }
689
690                 }
691             }
692         }
693         Iterator it = toberemoved.iterator();
694         while (it.hasNext()) {
695             vec.remove(it.next());
696         }
697         toberemoved.clear();
698         Collections.sort(vec);
699         me.merge_for_writes_done.put(inode, Boolean.TRUE);
700
701     }
702
703     public void non_Transactional_Write(byte[] data) {
704
705         Vector heldlocks = new Vector();
706         offsetlock.lock();
707         int startblock = FileBlockManager.getCurrentFragmentIndexofTheFile(committedoffset.getOffsetnumber());
708         int targetblock = FileBlockManager.getTargetFragmentIndexofTheFile(committedoffset.getOffsetnumber(), data.length);
709         for (int i = startblock; i <= targetblock; i++) {
710             BlockDataStructure block = this.inodestate.getBlockDataStructure(i);
711             block.getLock().writeLock().lock();
712             heldlocks.add(block.getLock().writeLock());
713
714         }
715
716         try {
717             invokeNativepwrite(data, committedoffset.getOffsetnumber(), data.length, file);
718             //file.seek(committedoffset.getOffsetnumber());
719             //file.write(data);
720             committedoffset.setOffsetnumber(committedoffset.getOffsetnumber() + data.length);
721
722         //} catch (IOException ex) {
723           //  Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
724         } finally {
725             unlockLocks(heldlocks);
726             offsetlock.unlock();
727         }
728     }
729
730     public int non_Transactional_Read(byte[] b) {
731         int size = -1;
732         Vector heldlocks = new Vector();
733         boolean flag = true;
734         offsetlock.lock();
735         int startblock;
736         int targetblock;
737         startblock = FileBlockManager.getCurrentFragmentIndexofTheFile(committedoffset.getOffsetnumber());
738         targetblock = FileBlockManager.getTargetFragmentIndexofTheFile(committedoffset.getOffsetnumber(), size);
739
740
741         for (int i = startblock; i <= targetblock; i++) {
742             BlockDataStructure block = this.inodestate.getBlockDataStructure(i);
743             block.getLock().readLock().lock();
744             heldlocks.add(block.getLock().readLock());
745         }
746
747         size = invokeNativepread(b, committedoffset.getOffsetnumber(), b.length);
748         committedoffset.setOffsetnumber(committedoffset.getOffsetnumber() + size);
749         if (!(committedoffset.getOffsetReaders().isEmpty())) {
750             Iterator it2 = committedoffset.getOffsetReaders().iterator(); // for visible readers strategy
751
752             while (it2.hasNext()) {
753                 ExtendedTransaction tr = (ExtendedTransaction) it2.next();
754                 tr.abort();
755             }
756             committedoffset.getOffsetReaders().clear();
757         }
758
759         unlockLocks(heldlocks);
760         offsetlock.unlock();
761         if (size == 0) {
762             size = -1;
763         }
764         return size;
765
766     }
767
768     public void non_Transactional_Seek(long offset) {
769         offsetlock.lock();
770         committedoffset.setOffsetnumber(offset);
771         offsetlock.unlock();
772     }
773
774     public long non_Transactional_getFilePointer() {
775         long offset = -1;
776
777         offsetlock.lock();
778         offset = committedoffset.getOffsetnumber();
779         offsetlock.unlock();
780
781         return offset;
782     }
783
784     public int compareTo(Object arg0) {
785         TransactionalFile tf = (TransactionalFile) arg0;
786         if (this.inode.getNumber() < tf.inode.getNumber()) {
787             return -1;
788         } else if (this.inode.getNumber() > tf.inode.getNumber()) {
789             return 1;
790         } else {
791             if (this.sequenceNum < tf.sequenceNum) {
792                 return -1;
793             } else {
794                 return 1;
795             }
796         }
797     }
798
799     public void makeWritestDependent(ExtendedTransaction me) {// make the writes absolute and dependent on ofset value
800
801         Iterator it;
802         if (me.getWriteBuffer().get(inode) != null) {
803             it = ((Vector) (me.getWriteBuffer().get(inode))).iterator();
804             while (it.hasNext()) {
805
806                 WriteOperations wrp = (WriteOperations) it.next();
807                 if (wrp.isUnknownoffset()) {
808                     wrp.setUnknownoffset(false);
809                     wrp.getOwnertransactionalFile().lockOffset(me);
810
811                     wrp.getRange().setStart(wrp.getOwnertransactionalFile().committedoffset.getOffsetnumber() - wrp.getBelongingto().getCopylocaloffset() + wrp.getRange().getStart());
812                     wrp.getRange().setEnd(wrp.getOwnertransactionalFile().committedoffset.getOffsetnumber() - wrp.getBelongingto().getCopylocaloffset() + wrp.getRange().getEnd());
813                     if ((wrp.getBelongingto().getOffsetdependency() == OffsetDependency.WRITE_DEPENDENCY_1) ||
814                             (wrp.getBelongingto().offsetdependency == OffsetDependency.NO_ACCESS) ||
815                             (wrp.getBelongingto().getOffsetdependency() == OffsetDependency.WRITE_DEPENDENCY_2)) {
816                         wrp.getBelongingto().setOffsetdependency(OffsetDependency.READ_DEPENDENCY);
817                         wrp.getBelongingto().setUnknown_inital_offset_for_write(false);
818                         if (!(wrp.getOwnertransactionalFile().committedoffset.getOffsetReaders().contains(me))) {
819                             wrp.getOwnertransactionalFile().committedoffset.getOffsetReaders().add(me);
820                         }
821                         wrp.getBelongingto().setLocaloffset(wrp.getBelongingto().getLocaloffset() + wrp.getOwnertransactionalFile().committedoffset.getOffsetnumber() - wrp.getBelongingto().getCopylocaloffset());
822                     }
823                     wrp.getOwnertransactionalFile().offsetlock.unlock();
824                     markAccessedBlocks(me, (int) wrp.getRange().getStart(), (int) (wrp.getRange().getEnd() - wrp.getRange().getStart()), BlockAccessModesEnum.WRITE);
825
826                 }
827             }
828         }
829
830     }
831 }
832 // for block versioning mechanism
833             /*if (!(validateBlocksVersions(startblock, targetblock))) { ////check to see if version are still valid 
834
835 throw new AbortedException();
836
837 }*/
838 /*  
839 int expvalue = ((Integer) tmp.getBlockversions().get(Integer.valueOf(k))).intValue();
840 while (me.getStatus() == Status.ACTIVE) {
841 BlockDataStructure block = ((BlockDataStructure) tmp.adapter.lockmap.get(Integer.valueOf(k)));
842 if (block.getLock().tryLock()) {
843 heldlocks.add(block.getLock());
844 if (!(block.getVersion().get() == expvalue)) {  // for block versioning mechanism
845 me.abort();
846
847 else {
848 break;
849 }
850
851 else {
852 me.getContentionManager().resolveConflict(me, block.getOwner());
853 }
854 }
855 if (me.getStatus() == Status.ABORTED) {
856 unlockLocks(heldlocks);
857 offsetlock.unlock();
858 throw new AbortedException();
859 }
860 }
861 }*/
862 /*    public boolean validateBlocksVersions(int startblock, int targetblock) { // For Block Versioning Mechanism
863 boolean valid = true;
864 ExtendedTransaction me = ExtendedTransaction.getTransaction();
865 TransactionLocalFileAttributes tmp = ((TransactionLocalFileAttributes) (me.getFilesAccesses().get(this.getInode())));
866 for (int i = startblock; i <= targetblock; i++) {
867 int expvalue = ((Integer) tmp.getBlockversions().get(Integer.valueOf(i))).intValue();
868 BlockDataStructure block = ((BlockDataStructure) tmp.adapter.lockmap.get(Integer.valueOf(i)));
869 if (expvalue != block.getVersion().get()) {
870 valid = false;
871 break;
872 }
873 }
874
875 return valid;
876 }*/
877
878