String normalizePath(UTF8 src) { String srcs = src.toString(); if (srcs.length() > 1 && srcs.endsWith("/")) { srcs = srcs.substring(0, srcs.length() - 1); } return srcs; }
/** * Load an edit log, and apply the changes to the in-memory structure * * <p>This is where we apply edits that we've been writing to disk all along. */ int loadFSEdits(File edits) throws IOException { int numEdits = 0; if (edits.exists()) { DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(edits))); try { while (in.available() > 0) { byte opcode = in.readByte(); numEdits++; switch (opcode) { case OP_ADD: { UTF8 name = new UTF8(); name.readFields(in); ArrayWritable aw = new ArrayWritable(Block.class); aw.readFields(in); Writable writables[] = (Writable[]) aw.get(); Block blocks[] = new Block[writables.length]; System.arraycopy(writables, 0, blocks, 0, blocks.length); unprotectedAddFile(name, blocks); break; } case OP_RENAME: { UTF8 src = new UTF8(); UTF8 dst = new UTF8(); src.readFields(in); dst.readFields(in); unprotectedRenameTo(src, dst); break; } case OP_DELETE: { UTF8 src = new UTF8(); src.readFields(in); unprotectedDelete(src); break; } case OP_MKDIR: { UTF8 src = new UTF8(); src.readFields(in); unprotectedMkdir(src.toString()); break; } default: { throw new IOException("Never seen opcode " + opcode); } } } } finally { in.close(); } } return numEdits; }
/** 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; } } }
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); } }
/** Add the given filename to the fs. */ public boolean addFile(UTF8 src, Block blocks[]) { waitForReady(); // Always do an implicit mkdirs for parent directory tree mkdirs(DFSFile.getDFSParent(src.toString())); if (unprotectedAddFile(src, blocks)) { logEdit(OP_ADD, src, new ArrayWritable(Block.class, blocks)); return true; } else { return false; } }
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; } } }
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()]); } } } }
/** Create the given directory and all its parent dirs. */ public boolean mkdirs(UTF8 src) { return mkdirs(src.toString()); }