comparison src/org/dancres/blitz/entry/WriteEntryOpInfo.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.entry;
2
3 import java.io.IOException;
4
5 import java.util.logging.*;
6
7 import net.jini.entry.AbstractEntry;
8 import org.dancres.blitz.disk.DiskTxn;
9
10 import org.dancres.blitz.mangler.MangledEntry;
11 import org.dancres.blitz.mangler.EntryMangler;
12
13 import org.dancres.blitz.txn.TxnState;
14
15 import org.dancres.blitz.oid.OID;
16
17 import org.dancres.blitz.arc.CacheBlockDescriptor;
18 import org.dancres.blitz.arc.RecoverySummary;
19
20 class WriteEntryOpInfo implements OpInfo {
21 static final long serialVersionUID = -6227846450032402193L;
22
23 private OID theOID;
24 private MangledEntry theEntry;
25 private long theInitialExpiry;
26
27 private transient boolean wasOnDisk;
28
29 WriteEntryOpInfo(EntrySleeveImpl aSleeve) {
30 theOID = aSleeve.getOID();
31 theInitialExpiry = aSleeve.getExpiry();
32 theEntry = aSleeve.getEntry();
33 }
34
35 public boolean isDebugOp() {
36 // Write's are never false though they can be aborted
37 //
38 return false;
39 }
40
41 public void restore() throws IOException {
42 EntryReposRecovery myRepos =
43 EntryRepositoryFactory.get().getAdmin(theEntry.getType());
44
45 if (myRepos == null) {
46 SleeveCache.theLogger.log(Level.SEVERE, "Yikes couldn't getAdmin");
47 throw new IOException("Couldn't getAdmin");
48 }
49
50 if (myRepos.noSchemaDefined()) {
51 DiskTxn myTxn = DiskTxn.newTxn();
52
53 myRepos.setFields(theEntry.getFields());
54
55 /*
56 Update parent repositories - each parent needs to know about
57 this subtype
58 */
59 String[] myParents = theEntry.tearOffParents();
60
61 for (int i = 0; i < myParents.length; i++) {
62 EntryRepository myParentRepos =
63 EntryRepositoryFactory.get().get(myParents[i]);
64 myParentRepos.addSubtype(theEntry.getType());
65 }
66
67 myTxn.commit();
68 }
69
70 EntrySleeveImpl mySleeve =
71 new EntrySleeveImpl(theOID, theEntry, theInitialExpiry);
72
73 RecoverySummary mySummary = myRepos.recover(mySleeve);
74
75 // If the entry was on disk, instance counts are already up-to-date
76 // so we don't want to count the entry twice
77 //
78 wasOnDisk = mySummary.wasOnDisk();
79
80 mySummary.getCBD().release();
81 }
82
83 public MangledEntry commit(TxnState aState) throws IOException {
84 MangledEntry myEntry = null;
85
86 EntryReposRecovery myRepos =
87 EntryRepositoryFactory.get().getAdmin(theEntry.getType());
88
89 CacheBlockDescriptor myCBD = myRepos.load(theOID);
90
91 if (myCBD != null) {
92 EntrySleeveImpl mySleeve = (EntrySleeveImpl) myCBD.getContent();
93
94 mySleeve.getState().clear(SleeveState.PINNED);
95
96 /**
97 * If Entry is deleted, lease has expired or we've taken it in
98 * the same transaction as this write. In those cases, we don't
99 * want to generate any events so we return null. Note that
100 * ENTRY_WRITE is generated elsewhere and thus writes remain
101 * visible event wise within transaction scope (i.e. for notify's
102 * on the transaction).
103 */
104 if (! mySleeve.getState().test(SleeveState.DELETED)) {
105 myEntry = theEntry;
106 // System.err.println("Wrote: " + theOID);
107 }
108
109 /*
110 If it wasOnDisk we needn't mark it dirty otherwise we must to
111 ensure the data reaches disk. We needn't mark it dirty any
112 earlier because if we crash prior to this stage, the Entry
113 shouldn't be written anyways.
114 */
115 if (!wasOnDisk)
116 mySleeve.markDirty();
117
118 myCBD.release();
119 }
120
121 // Update counters outside of lock
122 if (!wasOnDisk)
123 myRepos.getCounters().didWrite();
124
125 return myEntry;
126 }
127
128 public MangledEntry abort(TxnState aState) throws IOException {
129 EntryReposRecovery myRepos =
130 EntryRepositoryFactory.get().getAdmin(theEntry.getType());
131
132 CacheBlockDescriptor myCBD = myRepos.load(theOID);
133
134 if (myCBD != null) {
135 EntrySleeveImpl mySleeve = (EntrySleeveImpl) myCBD.getContent();
136
137 mySleeve.getState().set(SleeveState.DELETED);
138 mySleeve.getState().clear(SleeveState.PINNED);
139
140 /*
141 Write has been aborted, we need to ensure we do appropriate
142 cleanup.
143 */
144 mySleeve.markDirty();
145
146 myCBD.release();
147 }
148
149 return null;
150 }
151
152 public OID getOID() {
153 return theOID;
154 }
155
156 public String getType() {
157 return theEntry.getType();
158 }
159
160 public String toString() {
161 String myEntryRep = "Unusable";
162
163 try {
164 myEntryRep =
165 AbstractEntry.toString(
166 EntryMangler.getMangler().unMangle(theEntry));
167 } catch (Exception anE) {
168 // Nothing to do
169 myEntryRep = myEntryRep + ": " + anE.getClass();
170 }
171
172 return "W : " + theEntry.getType() + " : " + theOID + " : " +
173 theInitialExpiry + " : " + theEntry.sizeOf() + " : " +
174 theEntry.getCodebase() + " [ " + myEntryRep + " ]";
175 }
176 }