ABORTED, ACTIVE, COMMITTED
};
private boolean writesmerged = true;
+ private Vector heldlengthlocks;
//private Vector<ReentrantLock> heldoffsetlocks;
private Vector heldoffsetlocks;
//private Vector<ReentrantLock> heldblocklocks;
public ExtendedTransaction() {
// super();
// id = Integer.valueOf(Thread.currentThread().getName().substring(7));
+ heldlengthlocks = new Vector();
heldblocklocks = new Vector();
heldoffsetlocks = new Vector();
AccessedFiles = new HashMap();
public void addFile(TransactionalFile tf, long offsetnumber/*, TransactionLocalFileAttributes tmp*/) {
- TransactionLocalFileAttributes tmp = new TransactionLocalFileAttributes(offsetnumber/*, tf.getInodestate().commitedfilesize.get()*/);
+ TransactionLocalFileAttributes tmp = new TransactionLocalFileAttributes(offsetnumber, tf.getInodestate().commitedfilesize.getLength());
Vector dummy;
if (AccessedFiles.containsKey(tf.getInode())) {
Collections.sort(vec);
Iterator it = vec.iterator();
while (it.hasNext() /*&& this.getStatus() == Status.ACTIVE*/) {
- TransactionalFile value = (TransactionalFile) it.next();
+ TransactionalFile value = (TransactionalFile) it.next();
value.offsetlock.lock();
// toholoffsetlocks[offsetcount] = value.offsetlock;
// offsetcount++;
heldoffsetlocks.add(value.offsetlock);
+
+ if (((TransactionLocalFileAttributes) GlobaltoLocalMappings.get(value)).lenght_read){
+ if (!(value.getInodestate().commitedfilesize.lengthlock.isHeldByCurrentThread())){
+ value.getInodestate().commitedfilesize.lengthlock.lock();
+ heldlengthlocks.add(value.getInodestate().commitedfilesize.lengthlock);
+ }
+ }
break;
}
}
}
return true;
}
+
+
+
public boolean lockBlock(BlockDataStructure block, BlockAccessModesEnum mode/*, GlobalINodeState adapter, BlockAccessModesEnum mode, int expvalue, INode inode, TransactionLocalFileAttributes tf*/) {
if (this.status != Status.ACTIVE) {
throw new AbortedException();
}
- boolean ok = true;
+ boolean offsetsok = true;
if (!lockOffsets()) {
throw new AbortedException();
}
+
+ // boolean lengthslock = true;
+ // if (!lockOffsets()) {
+ // throw new AbortedException();
+ // }
///////////////////////////
Iterator iter = hm.keySet().iterator();
WriteOperations value;
Vector vec = new Vector();
- while (iter.hasNext() && (this.getStatus() == Status.ACTIVE) && ok) {
+ while (iter.hasNext() && (this.getStatus() == Status.ACTIVE) && offsetsok) {
INode key = (INode) iter.next();
vec = (Vector) hm.get(key);
Collections.sort(vec);
while (k.hasNext()) {
TransactionalFile trf = (TransactionalFile) (k.next());
trf.getCommitedoffset().setOffsetnumber(((TransactionLocalFileAttributes) GlobaltoLocalMappings.get(trf)).getLocaloffset());
+ if (((TransactionLocalFileAttributes) GlobaltoLocalMappings.get(trf)).getInitiallocallength() != ((TransactionLocalFileAttributes) GlobaltoLocalMappings.get(trf)).getLocalsize()){
+ try {
+ if (!(trf.getInodestate().commitedfilesize.lengthlock.isHeldByCurrentThread()))
+ trf.getInodestate().commitedfilesize.lengthlock.lock();
+
+ Iterator it2 = trf.getInodestate().commitedfilesize.getLengthReaders().iterator();
+ if (((TransactionLocalFileAttributes)getGlobaltoLocalMappings().get(trf)).getInitiallocallength() != ((TransactionLocalFileAttributes)getGlobaltoLocalMappings().get(trf)).getLocalsize())
+ {
+ while (it2.hasNext()) {
+ ExtendedTransaction tr = (ExtendedTransaction) it2.next();
+ if (tr != this) {
+ tr.abort();
+ }
+ }
+ trf.getInodestate().commitedfilesize.getLengthReaders().clear();
+ }
+ trf.getInodestate().commitedfilesize.setLength(trf.file.length());
+
+ if (trf.getInodestate().commitedfilesize.lengthlock.isHeldByCurrentThread()){
+ heldlengthlocks.remove(trf.getInodestate().commitedfilesize.lengthlock);
+ trf.getInodestate().commitedfilesize.lengthlock.unlock();
+ }
+
+ } catch (IOException ex) {
+ Logger.getLogger(ExtendedTransaction.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ if (((TransactionLocalFileAttributes) GlobaltoLocalMappings.get(trf)).lenght_read){
+ trf.getInodestate().commitedfilesize.getLengthReaders().remove(this);
+ heldlengthlocks.remove(trf.getInodestate().commitedfilesize.lengthlock);
+ trf.getInodestate().commitedfilesize.lengthlock.unlock();
+ }
}
lock.unlock();
}
heldoffsetlocks.clear();
+
+ it = heldlengthlocks.iterator();
+ while (it.hasNext()) {
+ ReentrantLock lock = (ReentrantLock) it.next();
+ lock.unlock();
+ }
+ heldlengthlocks.clear();
}
public void abortAllReaders() {
}
}
value.getCommitedoffset().getOffsetReaders().clear();
+
+
+
}
TreeMap vec2;
}
}
+
+
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.changes.addPropertyChangeListener("status", listener);
public Vector getHeldoffsetlocks() {
return heldoffsetlocks;
}
+
+ public Vector getHeldlengthlocks() {
+ return heldlengthlocks;
+ }
public void setHeldoffsetlocks(Vector heldoffsetlocks) {
this.heldoffsetlocks = heldoffsetlocks;
public HashMap lockmap;
private ConcurrentHashMap conlockmap = new ConcurrentHashMap();
- public AtomicLong commitedfilesize = new AtomicLong();
+ public GlobalLength commitedfilesize;
private ExtendedTransaction writer;
public int seqNum = 0;
private INode inode;
writer = null;
lockmap = new HashMap();
- commitedfilesize.set(length);
+ commitedfilesize = new GlobalLength(length);
this.inode = inode;
}
- public AtomicLong getCommitedfilesize() {
+ public GlobalLength getCommitedfilesize() {
return commitedfilesize;
}
- public void setCommitedfilesize(AtomicLong commitedfilesize) {
+ public void setCommitedfilesize(GlobalLength commitedfilesize) {
this.commitedfilesize = commitedfilesize;
}
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package TransactionalIO.core;
+
+import java.util.Vector;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ *
+ * @author navid
+ */
+public class GlobalLength {
+ private long length;
+ //private Vector<ExtendedTransaction> offsetReaders;
+ private Vector lengthReaders = new Vector();
+ private ExtendedTransaction offsetOwner;
+ public ReentrantLock lengthlock;
+
+ public GlobalLength(long length) {
+ this.length = length;
+ }
+
+
+ public long getLength() {
+ return length;
+ }
+
+
+ public void setLength(long offsetnumber) {
+ this.length = offsetnumber;
+ }
+
+ public Vector getLengthReaders() {
+ return lengthReaders;
+ }
+
+ public void setLengthReaders(Vector offsetReaders) {
+ this.lengthReaders = offsetReaders;
+ }
+
+}
private INode inode;
+ public boolean lenght_read = false;
public boolean to_be_created = false;
RandomAccessFile f;
OffsetDependency offsetdependency;
private long copylocaloffset;
+ private long initiallocallength;
private boolean unknown_inital_offset_for_write = true;
private long localoffset;
private long localsize;
- public TransactionLocalFileAttributes(long initialoffset/*, long initialsize*/){
+ public TransactionLocalFileAttributes(long initialoffset, long initialsize){
localoffset = initialoffset;
copylocaloffset = initialoffset;
+ localsize = initialsize;
+ initiallocallength = initialsize;
//copylocaloffset = 0;
+
unknown_inital_offset_for_write = true;
offsetdependency = OffsetDependency.NO_ACCESS;
//localsize = initialsize;
return copylocaloffset;
}
+ public long getInitiallocallength() {
+ return initiallocallength;
+ }
+
public void setCopylocaloffset(long copylocaloffset) {
this.copylocaloffset = copylocaloffset;
}
public boolean appendmode = false;
public ReentrantLock offsetlock;
private GlobalOffset committedoffset;
+
+
private GlobalINodeState inodestate;
Lock[] locks;
if (inodestate != null) {
synchronized (inodestate) {
committedoffset = new GlobalOffset(0);
+
}
}
}
if (inodestate != null) {
synchronized (inodestate) {
committedoffset = new GlobalOffset(0);
+
}
}
public GlobalOffset getCommitedoffset() {
return committedoffset;
}
+
+
+
public GlobalINodeState getInodestate() {
return inodestate;
}
-
+
public INode getInode() {
return inode;
}
Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
}
}
+
+
+ public long length(){
+ ExtendedTransaction me = Wrapper.getTransaction();
+
+ if (me == null) {
+ return non_Transactional_getFilePointer();
+ }
+
+ if (!(me.getGlobaltoLocalMappings().containsKey(this))) {
+ me.addFile(this, 0);
+ }
+
+ TransactionLocalFileAttributes tmp = (TransactionLocalFileAttributes) me.getGlobaltoLocalMappings().get(this);
+
+ lockLength(me);
+
+ if (!(this.inodestate.commitedfilesize.getLengthReaders().contains(me))) {
+ this.inodestate.commitedfilesize.getLengthReaders().add(me);
+ }
+ tmp.setLocalsize(this.inodestate.commitedfilesize.getLength());
+ tmp.lenght_read = true;
+
+ this.inodestate.commitedfilesize.lengthlock.unlock();
+ return tmp.getLocalsize();
+ }
public long getFilePointer() {
ExtendedTransaction me = Wrapper.getTransaction();
}
+ public final int readInt(){
+ byte[] data = new byte[4];
+ read(data);
+ int result = (data[0] << 24) | (data[1] << 16) + (data[2] << 8) + data[3];
+ return result;
+ }
+
+ public final long readLong(){
+ byte[] data = new byte[8];
+ read(data);
+ long result = ((long)data[0] << 56) + ((long)data[1] << 48) + ((long)data[2] << 40) + ((long)data[3] << 32) + ((long)data[4] << 24) + ((long)data[5] << 16)+ ((long)data[6] << 8) + data[7];
+ return result;
+ }
+
+ public final void writeInt(int value){
+ try {
+ byte[] result = new byte[4];
+ result[0] = (byte) (value >> 24);
+ result[1] = (byte) (value >> 16);
+ result[2] = (byte) (value >> 8);
+ result[3] = (byte) (value);
+ write(result);
+ } catch (IOException ex) {
+ Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+
+ public final void writeLong(long value){
+ try {
+ byte[] result = new byte[4];
+ result[0] = (byte)(value >> 56);
+ result[1] = (byte)(value >> 48);
+ result[2] = (byte)(value >> 40);
+ result[3] = (byte)(value >> 32);
+ result[4] = (byte)(value >> 24);
+ result[5] = (byte)(value >> 16);
+ result[6] = (byte)(value >> 8);
+ result[7] = (byte)(value);
+ write(result);
+ } catch (IOException ex) {
+ Logger.getLogger(TransactionalFile.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+
public int read(byte[] b) {
tmp.setLocaloffset(tmp.getLocaloffset() + by.length);
+
+ if (tmp.getLocaloffset() > tmp.getLocalsize())
+ tmp.setLocalsize(tmp.getLocaloffset());
me.merge_for_writes_done.put(inode, Boolean.FALSE);
}
+ public void lockLength(ExtendedTransaction me) {
+ boolean locked = false;
+ if (me.getStatus() == Status.ACTIVE) { //locking the offset
+
+ this.inodestate.commitedfilesize.lengthlock.lock();
+ locked = true;
+ }
+
+ if (me.getStatus() != Status.ACTIVE) {
+ if (locked) {
+ me.getHeldlengthlocks().add(this.inodestate.commitedfilesize.lengthlock);
+ }
+ throw new AbortedException();
+ }
+
+ }
+
public void mergeWrittenData(ExtendedTransaction me/*TreeMap target, byte[] data, Range to_be_merged_data_range*/) {
boolean flag = false;