junkaixue commented on code in PR #2607:
URL: https://github.com/apache/helix/pull/2607#discussion_r1325343901
##########
meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java:
##########
@@ -358,4 +358,25 @@ public static MetaClientException.ReturnCode
translateZooKeeperCodeToMetaClientC
return MetaClientException.ReturnCode.DB_USER_ERROR;
}
}
+
+ public static String getZkParentPath(String path) {
+ if (path.equals("/")) {
+ return null;
+ }
+
+ int idx = path.lastIndexOf('/');
+ return idx == 0 ? "/" : path.substring(0, idx);
Review Comment:
if idx ==0. It means the path is /xxxx. So the parent path should be null as
well.
##########
meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java:
##########
@@ -358,4 +358,25 @@ public static MetaClientException.ReturnCode
translateZooKeeperCodeToMetaClientC
return MetaClientException.ReturnCode.DB_USER_ERROR;
}
}
+
+ public static String getZkParentPath(String path) {
+ if (path.equals("/")) {
+ return null;
+ }
+
+ int idx = path.lastIndexOf('/');
+ return idx == 0 ? "/" : path.substring(0, idx);
+ }
+
+ // Splits a path into the paths for each node along the way.
+ // /a/b/c --> /a/b/c, /a/b, /a
+ public static List<String> separateIntoUniqueNodePaths(String path) {
Review Comment:
I would suggest the algorithm is like this:
List\<String\> nodePaths = new ArrayList<>();
String[] subPath = path.split("/");
StringBuilder tempPath = new StringBuilder();
for (int i = subPath.length - 1; i >= 1; i--) {
tempPath.insert(0, subPath[I]);
tempPath.insert(0, "/");
nodePaths.add(tempPath);
}
So this guarantee the list ordered by top parent path and you don't have to
search for index over and over again, which O(n^2) as n chars for paths.
##########
meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java:
##########
@@ -358,4 +358,25 @@ public static MetaClientException.ReturnCode
translateZooKeeperCodeToMetaClientC
return MetaClientException.ReturnCode.DB_USER_ERROR;
}
}
+
+ public static String getZkParentPath(String path) {
+ if (path.equals("/")) {
+ return null;
+ }
+
+ int idx = path.lastIndexOf('/');
+ return idx == 0 ? "/" : path.substring(0, idx);
+ }
+
+ // Splits a path into the paths for each node along the way.
+ // /a/b/c --> /a/b/c, /a/b, /a
+ public static List<String> separateIntoUniqueNodePaths(String path) {
+ ArrayList<String> nodePaths = new ArrayList<>();
Review Comment:
Usually java put interface not concrete class as type. So it should be:
List\<String\> nodePaths = new ArrayList<>();
##########
meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java:
##########
@@ -115,6 +116,52 @@ public void create(String key, Object data,
MetaClientInterface.EntryMode mode)
}
}
+ @Override
+ public void recursiveCreate(String key, T data, EntryMode mode) {
+ // Function named recursiveCreate to match naming scheme, but actual work
is iterative
+ iterativeCreate(key, data, mode, -1);
+ }
+
+ @Override
+ public void recursiveCreateWithTTL(String key, T data, long ttl) {
+ iterativeCreate(key, data, EntryMode.TTL, ttl);
+ }
+
+ private void iterativeCreate(String key, T data, EntryMode mode, long ttl) {
+ List<String> nodePaths = separateIntoUniqueNodePaths(key);
+ int i = 0;
+ // Ephemeral nodes cant have children, so change mode when creating parents
+ EntryMode parentMode = (EntryMode.EPHEMERAL.equals(mode) ?
+ EntryMode.PERSISTENT : mode);
+
+ // Iterate over paths, starting with full key then attempting each
successive parent
+ // Try /a/b/c, if fails due to NoNode then try /a/b .. etc..
+ while (i < nodePaths.size()) {
+ try {
+ if (EntryMode.TTL.equals(mode)) {
+ createWithTTL(nodePaths.get(i), data, ttl);
+ } else {
+ create(nodePaths.get(i), data, i == 0 ? mode : parentMode);
+ }
+ break;
+ // NoNodeException thrown when parent path does not exist. We allow
this and re-attempt
+ // creation of these nodes below
+ } catch (MetaClientNoNodeException ignoredParentDoesntExistException) {
+ i++;
+ }
+
+ }
+
+ // Reattempt creation of children that failed due to NoNodeException
+ while (--i >= 0) {
+ if (EntryMode.TTL.equals(mode)) {
+ createWithTTL(nodePaths.get(i), data, ttl);
+ } else {
+ create(nodePaths.get(i), data, i == 0 ? mode : parentMode);
+ }
+ }
+ }
Review Comment:
This require try catch that if two threads parallel creation the children at
the same time. Also I would imagine this should be same path as previous one.
@xyuanlu could you please help @GrantPSpencer walk through the idea?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]