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