📄 wizardcluster.java
字号:
public DxCollection allLockers() { DxCollection lockerIDs = lock.lockerIDs(); DxArrayBag result = new DxArrayBag(lockerIDs.count()); DxIterator it = lockerIDs.iterator(); while (it.next() != null) { result.add(env.transactionManager.taForID((TransactionID) it.object())); } return result; } /** Shadow files are contain the data of original cluster files. If the transaction involving the cluster fails, the cluster file data can be restored because it resides in the shadow file. */ protected void saveShadow() throws IOException { if (env != null) {// env.logWriter.newEntry( this, "saveShadow(): " + clusterID, LogWriter.DEBUG3 ); } String basename = clusterStore.basename(clusterID); File orig = new File(basename + ClusterStore.POSTFIX_CLUSTER); File shadow = new File(basename + ClusterStore.POSTFIX_SHADOW); // earlier versions did just _move_ the file; this was faster and caused // no problems because a abnormal server exit did force a recovery in any // case; this behaviour has changed and so we have to copy the file now // in order to keep an intact cluster // orig.renameTo( shadow ); // Why aren't we renaming here? This seems to be required. See the comments of ClusterStore.restoreCluster(). // Maybe we should rename _and_ copy from the shadow to the new cluster, not vice versa? InputStream in = null; OutputStream out = null; try { in = new FileInputStream(orig); out = new FileOutputStream(shadow); final int chunkSize = 4096; byte[] chunk = new byte[chunkSize]; int c = 0; while ((c = in.read(chunk)) != -1) { out.write(chunk, 0, c); } } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } /** * Restore the saved shadow on disk. The content of the receiver stays the * same. The cluster needs to be re-loaded to reflect the changes. */ protected void restoreShadow() throws IOException { if (env != null) {// env.logWriter.newEntry( this, "restoreShadow(): " + clusterID, LogWriter.DEBUG3 ); } // restore cluster on disk by renaming back shadow file String basename = clusterStore.basename(clusterID); File orig = new File(basename + ClusterStore.POSTFIX_CLUSTER); File shadow = new File(basename + ClusterStore.POSTFIX_SHADOW); // on Win renaming without prior deleting the target does not work; // long live WORA ! orig.delete(); if (!shadow.renameTo(orig)) { throw new IOException("Unable to rename shadow file."); } } protected void deleteShadow() throws IOException { if (env.logWriter.hasTarget(LogWriter.DEBUG3)) { env.logWriter.newEntry(this, "deleteShadow(): " + clusterID, LogWriter.DEBUG3); } String basename = clusterStore.basename(clusterID); File shadow = new File(basename + ClusterStore.POSTFIX_SHADOW); if (shadow.exists() && !shadow.delete()) { throw new IOException("Unable to delete shadow file."); } } /** * Delete this cluster from the disk. */ public void delete() throws Exception { String basename = clusterStore.basename(clusterID); new File(basename + ClusterStore.POSTFIX_CLUSTER).delete(); new File(basename + ClusterStore.POSTFIX_SHADOW).delete(); new File(basename + ClusterStore.POSTFIX_TEMP).delete(); new File(basename + ClusterStore.POSTFIX_LOCK).delete(); } public String toString() { return "WizardCluster[id=" + clusterID + "]"; } public Lock lock() { return lock; } public void setLock(Lock to) { //TODO: When can the lock be null and what is the significance of that? if (to == null) { if (env.logWriter.hasTarget(LogWriter.DEBUG)) { env.logWriter.newEntry(this, this + ".setLock(" + to + ") (oldLock=" + this.lock + "), isPinned()=" + isPinned() + ".", LogWriter.DEBUG); } } this.lock = to; } public void writeExternal(ObjectOutput out) throws IOException {// // cannot use logwriter because of nullpointer exception // if ((containers.count() == 0 && pinCount != 0) || (containers.count() > 0 && pinCount > 1)) {// System.out.println("pincount for " + this + " not 1 while writing (" + pinCount + " for " + containers.count() + " containers)");// } // System.out.println ("cluster.writeExternal()..."); out.writeByte(subSerialVersionUID); out.writeObject(clusterID); out.writeObject(permissions); out.writeLong(modTime); // out.writeObject (lock); out.writeInt(containers.count()); DxIterator it = containers.iterator(); StorageObjectContainer container; while ((container = (StorageObjectContainer) it.next()) != null) { // out.writeObject( container ); container.writeExternal(out); } } public void readExternal(ObjectInput in) throws IOException, ObjectStreamException, ClassNotFoundException { // System.out.println ("cluster.readExternal()..."); byte streamUID = in.readByte(); clusterID = (ClusterID) in.readObject(); permissions = (Permissions) in.readObject(); modTime = in.readLong(); // lock = (Lock)in.readObject(); int count = in.readInt(); for (int i = 0; i < count; i++) { try { // StorageObjectContainer container = (WizardObjectContainer)in.readObject(); StorageObjectContainer container = new WizardObjectContainer(); container.readExternal(in); container.setCluster(this);// Env.currentEnv().getLogWriter().newEntry(this,this+".readExternal(): container.id()="+container.id()+".",LogWriter.DEBUG2); containers.addForKey(container, container.id()); } catch (ObjectStreamException e) { if (env != null) { env.logWriter.newEntry(this, "ObjectStreamException for cluster " + clusterID + " at container #" + i + ": ", e, LogWriter.ERROR); } else { System.out.println("ObjectStreamException for cluster " + clusterID + " at container #" + i + ": " + e); } throw e; } } } /** Pins this WizardCluster. Every caller of this method must pair this call with a call to {@link #unpin}. A WizardCluster remains in main memory at least as long as it is pinned. */ public synchronized void pin() { int maxPinCount = (1 + containers.count()) * 1000; if (++pinCount > maxPinCount) { env.logWriter.newEntry(this, "pincount for " + this + " getting too large (" + pinCount + " for " + containers.count() + " containers)", LogWriter.ERROR); } } /** Unpins this WizardCluster. This method must be called exactly once for every call to {@link #pin}. */ public synchronized void unpin() { if (--pinCount < 0) { env.logWriter.newEntry(this, "pincount < 0 (" + pinCount + ") for " + this, LogWriter.WARN); clearPinCount(); // something is wrong with the pinning implementation if this happens so we need to signal this // but throwing an exception is a bit too strong // throw new OzoneInternalException("pincount < 0 for " + this); } } /** Returns wether this cluster is pinned. */ public synchronized boolean isPinned() { return pinCount != 0; } /** Sets the pin count to zero and returns the former pin count. */ public synchronized int clearPinCount() { int oldPinCount = pinCount; pinCount = 0; return oldPinCount; } /** Adds an amount to the pin count */ public synchronized void addPinCount(int what) { pinCount += what; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -