Browse Source

[partial-ns] Introduce Resolver.

Haohui Mai 10 năm trước cách đây
mục cha
commit
bc37594642

+ 5 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/DB.java

@@ -82,7 +82,7 @@ class DB {
     }
   }
 
-  private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+  private final ReentrantReadWriteLock lock;
 
   private HashMap<Long, INodeContainer> inodeMap = new
       HashMap<>();
@@ -107,4 +107,8 @@ class DB {
   ReentrantReadWriteLock lock() {
     return lock;
   }
+
+  DB(ReentrantReadWriteLock lock) {
+    this.lock = lock;
+  }
 }

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java

@@ -338,7 +338,7 @@ public class FSDirectory implements Closeable {
     namesystem = ns;
     this.editLog = ns.getEditLog();
     ezManager = new EncryptionZoneManager(this, conf);
-    this.db = new DB();
+    this.db = new DB(dirLock);
     // TODO: Load fsimage
     db.addRoot(createRootForFlatNS(ns));
   }

+ 81 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FlatINodesInPath.java

@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdfs.server.namenode;
+
+import com.google.common.collect.ImmutableList;
+import com.google.protobuf.ByteString;
+
+import java.util.AbstractMap;
+import java.util.Map;
+
+class FlatINodesInPath {
+  final ImmutableList<Map.Entry<ByteString, FlatINode>> inodes;
+
+  FlatINodesInPath(ImmutableList<Map.Entry<ByteString, FlatINode>> inodes) {
+    this.inodes = inodes;
+  }
+
+  public FlatINode getLastINode() {
+    return getLastINode(-1);
+  }
+
+  FlatINode getLastINode(int offset) {
+    return inodes.get(inodes.size() + offset).getValue();
+  }
+
+  ByteString getLastPathComponent() {
+    return getLastPathComponent(-1);
+  }
+
+  ByteString getLastPathComponent(int offset) {
+    return inodes.get(inodes.size() + offset).getKey();
+  }
+
+  String path() {
+    StringBuilder sb = new StringBuilder();
+    boolean addPrefix = false;
+    for (Map.Entry<ByteString, FlatINode> p : inodes) {
+      if (addPrefix) {
+        sb.append('/');
+      }
+      sb.append(p.getKey().toStringUtf8());
+      addPrefix = true;
+    }
+    return sb.toString();
+  }
+
+  ImmutableList<Map.Entry<ByteString, FlatINode>> inodes() {
+    return inodes;
+  }
+
+  public int length() {
+    return inodes.size();
+  }
+
+  static FlatINodesInPath concat(
+      FlatINodesInPath iip, Map.Entry<ByteString, FlatINode> last) {
+    ImmutableList<Map.Entry<ByteString, FlatINode>> l = ImmutableList.<Map.Entry<ByteString, FlatINode>>builder().addAll(
+        iip.inodes).add(last).build();
+    return new FlatINodesInPath(l);
+  }
+
+  static FlatINodesInPath addINode(
+      FlatINodesInPath iip, ByteString localName, FlatINode inode) {
+    return concat(iip, new AbstractMap.SimpleImmutableEntry<>(localName, inode));
+  }
+}

+ 154 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/Resolver.java

@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdfs.server.namenode;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.protobuf.ByteString;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.AbstractMap;
+import java.util.Map;
+
+class Resolver {
+  enum Error {
+    OK,
+    NOT_FOUND,
+    INVALID_PATH,
+  }
+
+  static final class Result {
+    final FlatINodesInPath iip;
+
+    final String src;
+    // The offset that points to the last unresolved component.
+    final int offset;
+    final Error errorCode;
+
+    private Result(
+        ImmutableList<Map.Entry<ByteString, FlatINode>> iip,
+        String src, int
+        offset, final Error errorCode) {
+      this.src = src;
+      this.iip = new FlatINodesInPath(iip);
+      this.offset = offset;
+      this.errorCode = errorCode;
+    }
+
+//    byte[] getLastKey() {
+//      return inodes.get(inodes.size() - 1).getKey();
+//    }
+    FlatINode getLastINode(int offset) {
+      return iip.getLastINode(offset);
+    }
+
+    public boolean ok() {
+      return errorCode == Error.OK;
+    }
+
+    public boolean invalidPath() {
+      return errorCode == Error.INVALID_PATH;
+    }
+
+    public boolean notFound() {
+      return errorCode == Error.NOT_FOUND;
+    }
+
+//    byte[] getLastComponent() { return Encoding.parseInodeKey(getLastKey())
+//      .getValue(); }
+
+    FlatINodesInPath inodesInPath() {
+      return iip;
+    }
+
+    String path() {
+      return iip.path();
+    }
+  }
+
+  static Result resolve(Transaction tx, final String path)
+      throws IOException {
+    long parentId = INodeId.ROOT_INODE_ID;
+    int offset = 0;
+    ImmutableList.Builder<Map.Entry<ByteString, FlatINode>> paths = ImmutableList
+      .builder();
+    paths.add(newPathEntry(Encoding.INODE_ROOT,
+                           tx.getINode(INodeId.ROOT_INODE_ID)));
+    int end = path.length();
+    while (end > 0 && path.charAt(end - 1) == '/') {
+      --end;
+    }
+    while (offset < end) {
+      if (path.charAt(offset) != '/') {
+        return new Result(paths.build(), path, offset, Error.INVALID_PATH);
+      }
+
+      int next = path.indexOf('/', offset + 1);
+      if (next == -1) {
+        next = end;
+      }
+      String component = path.substring(offset + 1, next);
+      long childId = tx.getChild(parentId, ByteBuffer.wrap(component.getBytes
+          ()));
+      if (childId == INodeId.INVALID_INODE_ID) {
+        return new Result(paths.build(), path, offset, Error.NOT_FOUND);
+      }
+      FlatINode child = tx.getINode(childId);
+      if (child == null) {
+        return new Result(paths.build(), path, offset, Error.NOT_FOUND);
+      }
+      paths.add(newPathEntry(component, child));
+      FlatINode inode = child;
+      offset = next;
+      parentId = inode.id();
+    }
+
+    return new Result(paths.build(), path, offset, Error.OK);
+  }
+
+  static Result resolveNoSymlink(Transaction tx, final String path)
+      throws IOException {
+    return resolve(tx, path);
+  }
+
+//  public static Result getInodeById(Transaction tx, long id)
+//    throws IOException {
+//    byte[] inodeKey = Encoding.inodeIdKey(id);
+//    byte[] realKey = tx.get(inodeKey);
+//    if (realKey == null) {
+//      return new Result(EMPTY_PATHS, 0, Error.NOT_FOUND);
+//    } else {
+//      byte[] value = tx.get(realKey);
+//      assert value != null;
+//      ImmutableList<Map.Entry<byte[], INode>> inodes = ImmutableList.of
+//        (newPathEntry(realKey, value));
+//      return new Result(inodes, 0, Error.OK);
+//    }
+//  }
+
+  private static Map.Entry<ByteString, FlatINode> newPathEntry(
+      ByteString key, FlatINode value) {
+    return new AbstractMap.SimpleImmutableEntry<>(key, value);
+  }
+
+  static Map.Entry<ByteString, FlatINode> newPathEntry(String key,
+      FlatINode value) {
+    return newPathEntry(ByteString.copyFromUtf8(key), value);
+  }
+}