我试图在内存中保留一组由以下模式标识的数据结构。我有一个粗略的解决方案,但我正在寻找一些更好的想法。性能和可靠性至关重要,内存不是那么多(在合理范围内),因为表格相当小(最多几百个条目,更可能是几十个)。我想,我宁愿不使用内存数据库来处理如此小的数据集。
我想要完成的是能够快速查询基于A.Name的所有B条目,基于B.Name的所有A条目,或基于T.Tag的所有A条目(我真的不需要)目前基于T.Tag的所有B条目,但将来可能会有用)
目前我使用三个具有重复数据的表,以及带来的同步问题,当我有一个新的数据时,我以三种不同的方式存储它。我相信必须有更好的方法。
// all A entries matching a tag
val Tag2A= new MutableHashMap[String, MutableSet[String]]() with MutableMultiMap[String, String]
// all B entries matching a tag
val Tag2B = new MutableHashMap[String, MutableSet[List[Int]]]() with MutableMultiMap[String, List[Int]]
// all Tags matching a A entry
val A2Tag = new MutableHashMap[String, MutableSet[String]]() with MutableMultiMap[String, String]
有人可以推荐更优雅的解决方案吗?
编辑:(澄清)我的MutableMultiMap和MutableSet只是mutable.MultiMap和mutable.Set在导入时别名。
EDIT2:表格需要修改(添加/删除)。
答案 0 :(得分:1)
假设您可以将所有内容加载到内存中,则可以接受不可变的解决方案:
abstract class A2B(tag: String) {
def aMap: Map[String, A]
def bMap: Map[String, B]
}
case class A(id: String, name: String, tag: A2B, payload: String)
case class B(id: String, name: String, tag: A2B, payload: List[Int])
您可以像这样初始化它(解决chicken-egg problem):
def getA2b(name: String): A2B = new A2B(name) {
val aMap = { //you can query your external data source tableA here
val a1 = "a1" -> A("a1", "a1", this, "aaaa")
val a2 = "a2" -> A("a2", "a2", this, "aaaa")
Map(a1, a2)
}
val bMap = { //you can query your external data source tableB here
val b1 = "b1" -> B("b1", "b1", this, Nil)
val b2 = "b2" -> B("b2", "b2", this, Nil)
Map(b1, b2)
}
override def toString = name
}
val a2b = Map("a2b1" -> getA2b("a2b1")) //you can query your external data source tableA2B here
以常量访问时间查询(抱歉当前机器上没有Scala REPL):
println(a2b("a2b1"))
println(a2b("a2b1").aMap)
println(a2b("a2b1").aMap("a1").tag.bMap)
a2b1
Map(a1 -> A(a1,a1,a2b1,aaaa), a2 -> A(a2,a2,a2b1,aaaa))
Map(b1 -> B(b1,b1,a2b1,List()), b2 -> B(b2,b2,a2b1,List()))
此处的所有关系都使用链接建模,因此没有开销。结构是不可变的,因此它是线程安全的。您还可以注意到A2B类在构造函数中被初始化(默认情况下所有的val都是final),因此根据JSR-133没有同步问题 - 您的应用程序总是看到A2B的最终版本,因此不需要挥发物。