Java Servlet->;具有非静态属性的Hashmap中的静态图

Java Servlet->;具有非静态属性的Hashmap中的静态图,java,servlets,graph,static,routing,Java,Servlets,Graph,Static,Routing,我有一个很大的图,它是在一个Javaservlet中处理的,用于路由目的。该图有100k+个节点,因此我无法为每个新呼叫重新加载它。此时,图形从我的数据库加载一次到RAM中,并在Hashmap中引用 当我启动servlet(创建一个新实例)时,我需要通过id在图中找到startnode。因此我使用hashmap 这一切都很好 我的问题是,在我的路线任务中,我需要更改图表中的某些属性,即行驶距离。当然,对于每个创建的实例,这些属性都必须是单独的。目前,我通过在创建新实例时重置所有“非静态”属性来处

我有一个很大的图,它是在一个Javaservlet中处理的,用于路由目的。该图有100k+个节点,因此我无法为每个新呼叫重新加载它。此时,图形从我的数据库加载一次到RAM中,并在Hashmap中引用

当我启动servlet(创建一个新实例)时,我需要通过id在图中找到startnode。因此我使用hashmap

这一切都很好

我的问题是,在我的路线任务中,我需要更改图表中的某些属性,即行驶距离。当然,对于每个创建的实例,这些属性都必须是单独的。目前,我通过在创建新实例时重置所有“非静态”属性来处理该任务。 这造成了两个问题

A) 这些实例不是线程安全的

B) 重置非常耗时。高达实际路由的10倍

因此,我需要的是Servlet所有实例的静态Hashmap。此Hashmap需要包含网络的所有节点。这些节点需要具有静态属性,如id、坐标、相邻节点等,但也需要具有非静态属性,如行驶距离

我该怎么做


感谢阅读和分享您的想法

您的问题可以描述为在运行时构建的模型,并在每次执行服务时实例化

当你说“静态”时,我想你的意思是“恒定”。变量属性实际上特定于每个执行,而不是每个Servlet实例。在执行过程中,您应该构建一个单独的结构,其中包含与常量属性并行的变量属性。变量结构中的每个节点引用常量结构中的单个节点。随着对每个节点的需求的增加,可变结构会逐渐根据需要构建。该结构在执行结束时被丢弃。

我建议以单例方式将“主图”保存在RAM中——正如Marko Topolnik建议的那样,但我只保留每个会话中更改的节点的映射,而不保留层次结构,只按ID存储它们(如果适用,本身)

  • 当会话结束时,您只需放弃会话中的映射,仅此而已
  • 当新会话开始时,只需创建一个新的映射实例
  • 如果这很关键的话,您也可以将这些映射合并在一起,但要避免过早的优化,因为这会导致比避免的问题多得多的问题
  • 如果需要访问某个节点,请从原始映射中获取该节点,然后在“会话本地”映射中查找该节点,如果找到,则合并两个节点中的数据。(或者,如果您在“会话本地”映射中存储完整节点,而不仅仅是更改的atributes,请使用该映射中更改的节点)
  • 另外,要小心,这有很多地方可能会导致内存泄漏

当你说“静态”时,我想你的意思是“恒定”。非常感谢你的快速回复。因此,根据你们两人的说法,不可能在图中使用同时包含常量和会话相关属性的对象。因此,方法是构建一个(哈希)映射,其中包含节点id引用的“影子”节点。该映射将在每次会话结束后删除。@Yojimbo:如果您愿意不惜一切代价这样做,您可以在每个节点中放置一个映射字段,用于存储更改,但这将是一个大问题。。。1.丑陋的。2.无法维护的。3.无限量的内存泄漏。4.可能会使用比其他任何东西都多的资源。。。是的,我建议在每个会话中使用这些阴影贴图(这个词很好,我喜欢!)。我同意贴图的IDE会非常难看。因为它应该是一个web服务,所以我们最终会在每个节点上都有大地图。因此,我想我将尝试为每个会话构建一个“阴影”映射。虽然我真的很想知道这会有多高效,因为我必须为我通过的每个节点读取该映射…@Yojimbo:由于会话映射相对较小(至少这是我从您所写的内容中假设的),我在这里看不到性能问题。相对较小意味着大约100k的读取和写入。我目前使用的缓慢复位机制大约需要100毫秒。实际的路由算法在10到40毫秒内执行。但我想我会尝试实现阴影贴图,并让您知道它有多快;)谢谢。我只是想知道如何从常量结构中引用变量结构。我是否应该像佩特卡建议的那样使用“会话本地”映射(使用id来引用)?它应该尽可能快…我想从变量结构中引用常量结构就足够了。您可以使用常量结构知道的
ThreadLocal
变量,该变量指向变量结构。不过,我很确定,您可以(而且可能应该)重构,以便所有代码都驻留在变量结构中,而固定结构不需要知道它。