private DataTree convertThisSnapShot() throws IOException { // create a datatree DataTree dataTree = new DataTree(); DataNodeV1 oldDataNode = oldDataTree.getNode(""); if (oldDataNode == null) { // should never happen LOG.error("Upgrading from an empty snapshot."); } recurseThroughDataTree(dataTree, ""); dataTree.lastProcessedZxid = oldDataTree.lastProcessedZxid; return dataTree; }
/** * deseriluize from an inputarchive * * @param oldTree the tree to be created * @param ia the input archive to be read from * @param sessions the sessions to be created * @throws IOException */ private void deserializeSnapshot(DataTreeV1 oldTree, InputArchive ia, Map<Long, Integer> sessions) throws IOException { int count = ia.readInt("count"); while (count > 0) { long id = ia.readLong("id"); int to = ia.readInt("timeout"); sessions.put(id, to); if (LOG.isTraceEnabled()) { ZooTrace.logTraceMessage( LOG, ZooTrace.SESSION_TRACE_MASK, "loadData --- session in archive: " + id + " with timeout: " + to); } count--; } oldTree.deserialize(ia, "tree"); }
/** * recurse through the old datatree and construct the new data tree * * @param dataTree the new datatree to be constructed * @param path the path to start with */ private void recurseThroughDataTree(DataTree dataTree, String path) { if (path == null) return; DataNodeV1 oldDataNode = oldDataTree.getNode(path); HashSet<String> children = oldDataNode.children; DataNode parent = null; if ("".equals(path)) { parent = null; } else { int lastSlash = path.lastIndexOf('/'); String parentPath = path.substring(0, lastSlash); parent = dataTree.getNode(parentPath); } DataNode thisDatNode = convertDataNode(dataTree, parent, oldDataNode); dataTree.addDataNode(path, thisDatNode); if (children == null || children.size() == 0) { return; } else { for (String child : children) { recurseThroughDataTree(dataTree, path + "/" + child); } } }
/** * play the log from this logstream into the datatree * * @param logStream * @return * @throws IOException */ public long playLog(InputArchive logStream) throws IOException { long highestZxid = 0; try { while (true) { byte[] bytes = logStream.readBuffer("txnEntry"); if (bytes.length == 0) { // Since we preallocate, we define EOF to be an // empty transaction throw new EOFException(); } InputArchive ia = BinaryInputArchive.getArchive(new ByteArrayInputStream(bytes)); TxnHeader hdr = new TxnHeader(); Record txn = SerializeUtils.deserializeTxn(ia, hdr); if (logStream.readByte("EOR") != 'B') { LOG.warn("Last transaction was partial."); throw new EOFException("Last transaction was partial."); } if (hdr.getZxid() <= highestZxid && highestZxid != 0) { LOG.error( highestZxid + "(higestZxid) >= " + hdr.getZxid() + "(next log) for type " + hdr.getType()); } else { highestZxid = hdr.getZxid(); } switch (hdr.getType()) { case OpCode.createSession: sessionsWithTimeouts.put(hdr.getClientId(), ((CreateSessionTxn) txn).getTimeOut()); if (LOG.isTraceEnabled()) { ZooTrace.logTraceMessage( LOG, ZooTrace.SESSION_TRACE_MASK, "playLog --- create session in log: 0x" + Long.toHexString(hdr.getClientId()) + " with timeout: " + ((CreateSessionTxn) txn).getTimeOut()); } // give dataTree a chance to sync its lastProcessedZxid oldDataTree.processTxn(hdr, txn); break; case OpCode.closeSession: sessionsWithTimeouts.remove(hdr.getClientId()); if (LOG.isTraceEnabled()) { ZooTrace.logTraceMessage( LOG, ZooTrace.SESSION_TRACE_MASK, "playLog --- close session in log: 0x" + Long.toHexString(hdr.getClientId())); } oldDataTree.processTxn(hdr, txn); break; default: oldDataTree.processTxn(hdr, txn); } Request r = new Request(null, 0, hdr.getCxid(), hdr.getType(), null, null); r.txn = txn; r.hdr = hdr; r.zxid = hdr.getZxid(); } } catch (EOFException e) { // expected in some cases - see comments in try block } return highestZxid; }