1 9 package org.ozoneDB.core.storage.magicStore; 10 11 import java.io.Externalizable ; 12 import java.io.File ; 13 import java.io.IOException ; 14 import java.io.ObjectInput ; 15 import java.io.ObjectOutput ; 16 import java.io.ObjectStreamException ; 17 import org.ozoneDB.DxLib.DxArrayBag; 18 import org.ozoneDB.DxLib.DxCollection; 19 import org.ozoneDB.DxLib.DxHashMap; 20 import org.ozoneDB.DxLib.DxIterator; 21 import org.ozoneDB.DxLib.DxLong; 22 import org.ozoneDB.core.Lock; 23 import org.ozoneDB.core.MROWLock; 24 import org.ozoneDB.core.Permissions; 25 import org.ozoneDB.core.Transaction; 26 import org.ozoneDB.core.TransactionID; 27 import org.ozoneDB.core.storage.*; 28 import org.ozoneDB.util.LogWriter; 29 30 31 32 41 public final class MagicCluster extends org.ozoneDB.core.wizardStore.Cluster implements Externalizable { 42 43 protected final static long serialVersionUID = 2L; 44 protected final static byte subSerialVersionUID = 1; 45 46 protected transient MROWLock lock; 47 48 protected transient long lastTouched; 49 50 protected transient int bytesPerContainer; 51 52 protected long modTime; 53 54 56 59 public MagicCluster() { 60 this(null, null, null, 0); 61 } 62 63 64 public MagicCluster(ClusterID _clusterID, Permissions _permissions, MROWLock lock, int _bpc) { 65 clusterID = _clusterID; 67 permissions = _permissions; 68 this.lock = lock; 69 bytesPerContainer = _bpc; 70 containers = new DxHashMap(1024); 71 if (lock != null) { 72 lock.setDebugInfo("clusterID=" + clusterID); 73 } 74 } 76 77 public void addedTo(Cache addedTo, Object key) { 78 } 80 81 public void removedFrom(Cache removedFrom, Object key) { 82 } 84 85 public void delete() throws Exception { 86 File clusterFile = new File (clusterStore.basename(clusterID) + ClusterStore.POSTFIX_CLUSTER); 87 if (!clusterFile.delete()) { 88 throw new IOException ("Could not delete cluster file " + clusterFile); 89 } 90 } 91 92 93 protected synchronized void unregister() { 94 } 96 97 protected void finalize() { 98 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 99 env.logWriter.newEntry(this, "---finalize(): cluster " + clusterID, LogWriter.DEBUG3); 100 } 101 102 if (lock.level(null) >= Lock.LEVEL_READ) { 104 if (env.logWriter.hasTarget(LogWriter.DEBUG)) { 105 env.logWriter.newEntry(this, " write lock to disk: " + clusterID, LogWriter.DEBUG); 106 } 107 108 try { 109 ((ClusterStore)clusterStore).storeDataImmediately(lock(), clusterStore.basename(clusterID) + ClusterStore.POSTFIX_LOCK); 110 } catch (IOException e) { 111 env.logWriter.newEntry(this, "could not write cluster lock " + clusterID, LogWriter.ERROR); 112 } 113 } else { 114 File lockFile = new File (clusterStore.basename(clusterID) + ClusterStore.POSTFIX_LOCK); 115 if (lockFile.exists()) { 116 lockFile.delete(); 117 } 118 } 119 120 if (lock.level(null) > Lock.LEVEL_UPGRADE) { 122 if (env.logWriter.hasTarget(LogWriter.DEBUG)) { 123 env.logWriter.newEntry(this, " write cluster: " + clusterID, LogWriter.DEBUG); 124 } 125 126 TransactionID taID = lock.getWriteLockingTransactionID(); 127 if (taID == null) { 128 env.logWriter.newEntry(this, "BUG: cluster is write locked but cannot find locker transaction id" + clusterID, LogWriter.ERROR); 129 } 130 try { 131 ((ClusterStore)clusterStore).storeDataImmediately(this, clusterStore.basename(clusterID) + ClusterStore.POSTFIX_SEPARATOR + taID.value() + ClusterStore.POSTFIX_CLUSTER); 132 } catch (IOException e) { 133 env.logWriter.newEntry(this, "could not write cluster lock " + clusterID, LogWriter.ERROR); 134 } 135 } 136 137 setLock(null); 139 140 unregister(); 141 } 142 143 144 public long modTime() { 145 return modTime; 146 } 147 148 149 154 public DxLong cachePriority() { 155 return new DxLong(lastTouched); 156 } 157 158 159 public synchronized void setCurrentSize(int byteSize) { 160 int containerCount = containers.count(); 161 bytesPerContainer = containerCount > 0 ? byteSize / containerCount : clusterStore.currentBytesPerContainer(); 162 } 163 164 165 public int size() { 166 return containers.count() * bytesPerContainer; 167 } 168 169 170 public ClusterID clusterID() { 171 return clusterID; 172 } 173 174 175 178 public boolean isInvoked() { 179 StorageObjectContainer container; 182 DxIterator it = containers.iterator(); 183 while ((container = (StorageObjectContainer) it.next()) != null) { 184 if (container.isInvoked()) { 185 return true; 186 } 187 } 188 return false; 189 } 190 191 192 public synchronized void touch() { 193 lastTouched = clusterStore.touchCount++; 194 } 195 196 197 202 public void updateLockLevel(Transaction ta) throws IOException { 203 if (env.logWriter.hasTarget(LogWriter.DEBUG2)) { 204 env.logWriter.newEntry(this, "updateLockLevel(): " + clusterID, LogWriter.DEBUG2); 205 env.logWriter.newEntry(this, " lock: " + lock.level(ta), LogWriter.DEBUG2); 206 } 207 } 208 209 210 public void prepareCommit(Transaction ta) { 211 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 212 env.logWriter.newEntry(this, "prepareCommit()" + clusterID, LogWriter.DEBUG3); 213 } 214 if (lock.level(ta) > Lock.LEVEL_UPGRADE) { 215 synchronized (this) { 216 modTime = System.currentTimeMillis(); 217 } 218 } 219 } 220 221 222 public void commit(Transaction ta) throws IOException { 223 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 224 env.logWriter.newEntry(this, "commit()" + clusterID, LogWriter.DEBUG3); 225 } 226 227 if (true || lock != null) { 228 lock.release(ta); 229 } else { 230 throw new NullPointerException (this + ".commit(" + ta + "): lock=" + lock + "."); 232 } 233 } 234 235 236 public void abort(Transaction ta) throws IOException { 237 if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { 238 env.logWriter.newEntry(this, "abort()" + clusterID, LogWriter.DEBUG3); 239 } 240 241 if (true || lock != null) { 242 lock.release(ta); 243 } else { 244 throw new NullPointerException (this + ".abort(" + ta + "): lock=" + lock + "."); 245 } 246 } 247 248 public DxCollection allLockers() { 249 DxCollection lockerIDs = lock.lockerIDs(); 250 251 DxArrayBag result = new DxArrayBag(lockerIDs.count()); 252 DxIterator it = lockerIDs.iterator(); 253 while (it.next() != null) { 254 result.add(env.transactionManager.taForID((TransactionID) it.object())); 255 } 256 257 return result; 258 } 259 260 public String toString() { 261 return "MagicCluster[id=" + clusterID + "]"; 262 } 263 264 public Lock lock() { 265 return lock; 266 } 267 268 public void setLock(Lock to) { 269 if (to == null) { 271 if (env.logWriter.hasTarget(LogWriter.DEBUG)) { 272 env.logWriter.newEntry(this, this + ".setLock(" + to + ") (oldLock=" + this.lock + ").", LogWriter.DEBUG); 273 } 274 } 275 276 this.lock = (MROWLock) to; 277 } 278 279 public void writeExternal(ObjectOutput out) throws IOException { 280 out.writeByte(subSerialVersionUID); 286 out.writeObject(clusterID); 287 out.writeObject(permissions); 288 out.writeLong(modTime); 289 291 out.writeInt(containers.count()); 292 DxIterator it = containers.iterator(); 293 StorageObjectContainer container; 294 while ((container = (StorageObjectContainer) it.next()) != null) { 295 container.writeExternal(out); 297 } 298 } 299 300 301 public void readExternal(ObjectInput in) throws IOException , ObjectStreamException , ClassNotFoundException { 302 byte subSerialUID = in.readByte(); 304 clusterID = (ClusterID) in.readObject(); 305 permissions = (Permissions) in.readObject(); 306 modTime = in.readLong(); 307 309 int count = in.readInt(); 310 for (int i = 0; i < count; i++) { 311 try { 312 StorageObjectContainer container = new MagicObjectContainer(); 314 container.readExternal(in); 315 container.setCluster(this); 316 containers.addForKey(container, container.id()); 318 } catch (ObjectStreamException e) { 319 if (env != null) { 320 env.logWriter.newEntry(this, "ObjectStreamException for cluster " + clusterID + " at container #" + i + ": ", e, LogWriter.ERROR); 321 } else { 322 System.out.println("ObjectStreamException for cluster " + clusterID + " at container #" + i + ": " + e); 323 } 324 throw e; 325 } 326 } 327 } 328 329 330 } 331 | Popular Tags |