/** Create directory entries for every item */ boolean mkdirs(String src) { src = normalizePath(new UTF8(src)); // Use this to collect all the dirs we need to construct Vector v = new Vector(); // The dir itself v.add(src); // All its parents String parent = DFSFile.getDFSParent(src); while (parent != null) { v.add(parent); parent = DFSFile.getDFSParent(parent); } // Now go backwards through list of dirs, creating along // the way boolean lastSuccess = false; int numElts = v.size(); for (int i = numElts - 1; i >= 0; i--) { String cur = (String) v.elementAt(i); INode inserted = unprotectedMkdir(cur); if (inserted != null) { logEdit(OP_MKDIR, new UTF8(inserted.computeName()), null); lastSuccess = true; } else { lastSuccess = false; } } return lastSuccess; }
/** Save the contents of the FS image */ void saveFSImage(File fullimage, File edits) throws IOException { File curFile = new File(fullimage, FS_IMAGE); File newFile = new File(fullimage, NEW_FS_IMAGE); File oldFile = new File(fullimage, OLD_FS_IMAGE); // // Write out data // DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(newFile))); try { out.writeInt(rootDir.numItemsInTree() - 1); rootDir.saveImage("", out); } finally { out.close(); } // // Atomic move sequence // // 1. Move cur to old curFile.renameTo(oldFile); // 2. Move new to cur newFile.renameTo(curFile); // 3. Remove pending-edits file (it's been integrated with newFile) edits.delete(); // 4. Delete old oldFile.delete(); }
long computeContentsLength() { long total = computeFileLength(); for (Iterator it = children.values().iterator(); it.hasNext(); ) { INode child = (INode) it.next(); total += child.computeContentsLength(); } return total; }
int numItemsInTree() { int total = 0; for (Iterator it = children.values().iterator(); it.hasNext(); ) { INode child = (INode) it.next(); total += child.numItemsInTree(); } return total + 1; }
/** * Collect all the blocks at this INode and all its children. This operation is performed after * a node is removed from the tree, and we want to GC all the blocks at this node and below. */ void collectSubtreeBlocks(Vector v) { if (blocks != null) { for (int i = 0; i < blocks.length; i++) { v.add(blocks[i]); } } for (Iterator it = children.values().iterator(); it.hasNext(); ) { INode child = (INode) it.next(); child.collectSubtreeBlocks(v); } }
INode getNode(Vector components, int index) { if (!name.equals((String) components.elementAt(index))) { return null; } if (index == components.size() - 1) { return this; } // Check with children INode child = (INode) children.get(components.elementAt(index + 1)); if (child == null) { return null; } else { return child.getNode(components, index + 1); } }
String computeName() { if (parent != null) { return parent.computeName() + "/" + name; } else { return name; } }
/** Check whether the filepath could be created */ public boolean isValidToCreate(UTF8 src) { String srcs = normalizePath(src); synchronized (rootDir) { if (srcs.startsWith("/") && !srcs.endsWith("/") && rootDir.getNode(srcs) == null) { return true; } else { return false; } } }
void saveImage(String parentPrefix, DataOutputStream out) throws IOException { String fullName = ""; if (parent != null) { fullName = parentPrefix + "/" + name; new UTF8(fullName).write(out); if (blocks == null) { out.writeInt(0); } else { out.writeInt(blocks.length); for (int i = 0; i < blocks.length; i++) { blocks[i].write(out); } } } for (Iterator it = children.values().iterator(); it.hasNext(); ) { INode child = (INode) it.next(); child.saveImage(fullName, out); } }
/** Get the blocks associated with the file */ public Block[] getFile(UTF8 src) { waitForReady(); synchronized (rootDir) { INode targetNode = rootDir.getNode(src.toString()); if (targetNode == null) { return null; } else { return targetNode.blocks; } } }
/** * Get a listing of files given path 'src' * * <p>This function is admittedly very inefficient right now. We'll make it better later. */ public DFSFileInfo[] getListing(UTF8 src) { String srcs = normalizePath(src); synchronized (rootDir) { INode targetNode = rootDir.getNode(srcs); if (targetNode == null) { return null; } else { Vector contents = new Vector(); targetNode.listContents(contents); DFSFileInfo listing[] = new DFSFileInfo[contents.size()]; int i = 0; for (Iterator it = contents.iterator(); it.hasNext(); i++) { listing[i] = new DFSFileInfo((INode) it.next()); } return listing; } } }
boolean unprotectedAddFile(UTF8 name, Block blocks[]) { synchronized (rootDir) { if (blocks != null) { // Add file->block mapping for (int i = 0; i < blocks.length; i++) { activeBlocks.add(blocks[i]); } } return (rootDir.addNode(name.toString(), blocks) != null); } }
Block[] unprotectedDelete(UTF8 src) { synchronized (rootDir) { INode targetNode = rootDir.getNode(src.toString()); if (targetNode == null) { return null; } else { // // Remove the node from the namespace and GC all // the blocks underneath the node. // if (!targetNode.removeNode()) { return null; } else { Vector v = new Vector(); targetNode.collectSubtreeBlocks(v); for (Iterator it = v.iterator(); it.hasNext(); ) { Block b = (Block) it.next(); activeBlocks.remove(b); } return (Block[]) v.toArray(new Block[v.size()]); } } } }
boolean unprotectedRenameTo(UTF8 src, UTF8 dst) { synchronized (rootDir) { INode removedNode = rootDir.getNode(src.toString()); if (removedNode == null) { return false; } removedNode.removeNode(); if (isDir(dst)) { dst = new UTF8(dst.toString() + "/" + new File(src.toString()).getName()); } INode newNode = rootDir.addNode(dst.toString(), removedNode.blocks); if (newNode != null) { newNode.children = removedNode.children; for (Iterator it = newNode.children.values().iterator(); it.hasNext(); ) { INode child = (INode) it.next(); child.parent = newNode; } return true; } else { rootDir.addNode(src.toString(), removedNode.blocks); return false; } } }
INode unprotectedMkdir(String src) { synchronized (rootDir) { return rootDir.addNode(src, null); } }
/** Check whether the path specifies a directory */ public boolean isDir(UTF8 src) { synchronized (rootDir) { INode node = rootDir.getNode(normalizePath(src)); return node != null && node.isDir(); } }