java中多线程构造不可变树的算法

发布于 2024-10-17 14:27:35 字数 161 浏览 6 评论 0原文

我想构建一个不可变树数据结构来表示filsystem目录结构的任意子集。通常会有一个知道包含/排除的过滤器,我基本上希望在构造中拥有一些线程支持。

这听起来像是我自己编写代码的纯粹书呆子的乐趣,但我实际上想知道关于这个主题是否有任何好的例子、文本或类似的东西?源代码很好;)

I would like to build an immutable tree data structure representing an arbitrary subset of a filsystem directory structure. There would typically be a filter that knows about include/exclude and I would basically want to have some threading support in the construction.

This sounds like pure nerd fun to code myself, but I am actually wondering if there are any good examples, texts or similar on this topic ? Source code is nice ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雨巷深深 2024-10-24 14:27:35

我不知道这是否有帮助。
Java SortedMap 使用红黑树,您可以在此处查看源代码。

 https://www.docjar.com/html/api/org/eclipse/ant/internal/ui/dtd/util/SortedMap.java.html

对于不可修改的 SortedMap。你可以在这里看到 Collections.unmodifyingSortepMap 的源代码

http://www.docjar.com/html/api/java/util/Collections.java.html

I dont know whether this is helpful.
Java SortedMap uses red black tree and you can look at the source code here.

 https://www.docjar.com/html/api/org/eclipse/ant/internal/ui/dtd/util/SortedMap.java.html

For unmodifiable SortedMap. u can see the source code for Collections.unmodifiableSortepMap here

http://www.docjar.com/html/api/java/util/Collections.java.html
冰雪梦之恋 2024-10-24 14:27:35

我建议维护一个“工作项目”队列。每个工作项都封装了一个要探索的目录,以及一个要将生成的树节点附加到的现有父节点(如果有)。每个线程都在循环中执行,从队列前端拉出项目,执行它们,并将任何子目录作为新工作项目推送到队列末尾。

您可以通过将根目录(没有父树节点)作为第一个工作项来启动该过程。当队列为空并且所有线程都处于空闲/等待状态时,该过程结束。

上面假设树一旦构造成不可变,但在构造过程中是可变的。如果情况并非如此,您需要“自下而上”构建树,因此您需要一个临时的可变结构来保存要附加的节点。否则,过程应该是相同的。

I would suggest maintaining a queue of 'work items'. Each work item encapsulates a directory to explore, and an existing parent node (if any) to attach the resulting tree node to. Each thread executes in a loop, pulling items off the front of the queue, executing them, and pushing any subdirectories onto the end of the queue as new work items.

You start the process by pushing the root directory (with no parent tree node) as the first work item. The process is finished when the queue is empty, and all the threads are idle/waiting.

The above assumes that the tree will be immutable once constructed, but is mutable during construction. If that's not the case, you need to build the tree 'bottom up', so you'll need a temporary, mutable structure to hold nodes as they're being appended to. Otherwise, the process should be the same.

空名 2024-10-24 14:27:35

To krosenvold:

我认为你还没有理解我的意图。也许我应该把自己说得更清楚。

假设 Tree 和 TreeBuilder 位于同一个包中。

正如您所看到的,Tree 构造函数和 freeze() 方法具有级别访问权限。因此,您不能在包外创建它,也不能在包外冻结它。

唯一的方法是通过 build() 方法。只有 TreeBuilder 可以使用同步的 build 方法创建 Tree。

现在我什至意识到,您甚至可以更简单地删除只读标志并更改 Tree.addChild() 方法以打包可见性。因此,您将得到一棵没有公共变异器、只有访问器的树。

就像我说的,树不同步。 TreeBuilder 是进行同步的地方。仔细看看访问器和修改器。查看公共和包修饰符的位置,您会发现修改树的唯一方法是当您位于同一个包中时,因此只有树构建器能够执行此操作。

public class Tree<T extends Filterable>{
   private final T data;
   private Tree<T> parent;
   private List<Tree<T>> children;
   private List<FilterChain<T>> filterChain;
   private boolean readonly = false;  
   /*package*/ Tree(T data) {...} 
   /*package*/ Tree(Tree<T> parent, T data) {...}

   /*package*/ void addChild(Tree<T> child){
       children.add(child);
   }
   public List<?> getResults(){
       return data.returnResults(filterChain);
   }

}

public class TreeBuilder<T>{
  public synchronized TreeNode createRoot(T data);
  public synchronized void addSubElement(TreeNode parentNode ,T data);
  public synchronized void addFilter(TreeNode node, Filter<T> filter);
  public Tree<T> synchronized build(){
     Tree<T> tree= ... 
     //build your tree
     //build filter chain for specific tree node
     return tree;
  }

}

To krosenvold:

I think that you haven't understood my intention. Maybe I should make myself more clear.

Assumptions are that Tree and TreeBuilder are in the same package.

As you can see Tree constructor and freeze() method have package level access. So you can't create it outside of the package and you can't freeze it outside of package as well.

The only way to do that is via build() method. Only TreeBuilder can create Tree using build method which is synchronized.

Now I even realized that you may even make it simpler removing readonly flag at all and changing Tree.addChild() method to package visibility as well. Hence you will get a tree which has no public mutators only accessors.

Like I said Tree does no synchronization. TreeBuilder is where your synchronization takes place. Have a closer look on the accessors and mutators. Look where public and package modifiers are located and you will see that the only way to modify the tree is when you are in the same package so only tree builder is capable of doing it.

public class Tree<T extends Filterable>{
   private final T data;
   private Tree<T> parent;
   private List<Tree<T>> children;
   private List<FilterChain<T>> filterChain;
   private boolean readonly = false;  
   /*package*/ Tree(T data) {...} 
   /*package*/ Tree(Tree<T> parent, T data) {...}

   /*package*/ void addChild(Tree<T> child){
       children.add(child);
   }
   public List<?> getResults(){
       return data.returnResults(filterChain);
   }

}

public class TreeBuilder<T>{
  public synchronized TreeNode createRoot(T data);
  public synchronized void addSubElement(TreeNode parentNode ,T data);
  public synchronized void addFilter(TreeNode node, Filter<T> filter);
  public Tree<T> synchronized build(){
     Tree<T> tree= ... 
     //build your tree
     //build filter chain for specific tree node
     return tree;
  }

}

遗忘曾经 2024-10-24 14:27:35

您好,我不知道您到底想要实现什么,特别是在线程安全方面,但也许下面的伪代码可以用作草案。

public interface Filterable {
     List<?> returnResults(FilterChain chain);
} 

public class Tree<T extends Filterable>{
   private final T data;
   private Tree<T> parent;
   private List<Tree<T>> children;
   private List<FilterChain<T>> filterChain;
   private boolean readonly = false;  
   /*package*/ Tree(T data) {...} 
   /*package*/ Tree(Tree<T> parent, T data) {...}

   //freeze mtd makes object read-only
   /*package*/ void freeze(){         
          readonly = true;
      for(Tree<T> child: children){
          child.freeze();
      }
   }
   public void addChild(Tree<T> child){
       if(readonly){
           throws new NonModifiableException(...);
       }
       children.add(child);
   }
   public List<?> getResults(){
       return data.returnResults(filterChain);
   }

}

也许您可以专注于在树的构建器上进行同步,而不是在树上进行同步

public class TreeBuilder<T>{
    public synchronized TreeNode createRoot(T data);
    public synchronized void addSubElement(TreeNode parentNode ,T data);
    public synchronized void addFilter(TreeNode node, Filter<T> filter);
    public Tree<T> synchronized build(){
       Tree<T> tree= ... 
       //build your tree
       //build filter chain for specific tree node
       tree.freeze(); //make your tree readonly
       return tree;
    }
}

Hi I don't know what exactly would you like to achive especially in terms of thread-safety but maybe below pseudocode could be used as a draft.

public interface Filterable {
     List<?> returnResults(FilterChain chain);
} 

public class Tree<T extends Filterable>{
   private final T data;
   private Tree<T> parent;
   private List<Tree<T>> children;
   private List<FilterChain<T>> filterChain;
   private boolean readonly = false;  
   /*package*/ Tree(T data) {...} 
   /*package*/ Tree(Tree<T> parent, T data) {...}

   //freeze mtd makes object read-only
   /*package*/ void freeze(){         
          readonly = true;
      for(Tree<T> child: children){
          child.freeze();
      }
   }
   public void addChild(Tree<T> child){
       if(readonly){
           throws new NonModifiableException(...);
       }
       children.add(child);
   }
   public List<?> getResults(){
       return data.returnResults(filterChain);
   }

}

Instead of making synchronization on the Tree maybe you could focus on making synchronization on the builder of the tree

public class TreeBuilder<T>{
    public synchronized TreeNode createRoot(T data);
    public synchronized void addSubElement(TreeNode parentNode ,T data);
    public synchronized void addFilter(TreeNode node, Filter<T> filter);
    public Tree<T> synchronized build(){
       Tree<T> tree= ... 
       //build your tree
       //build filter chain for specific tree node
       tree.freeze(); //make your tree readonly
       return tree;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文