使用哈希表的关系数据

时间:2015-10-02 19:11:15

标签: scala

我试图在内存中保留一组由以下模式标识的数据结构。我有一个粗略的解决方案,但我正在寻找一些更好的想法。性能和可靠性至关重要,内存不是那么多(在合理范围内),因为表格相当小(最多几百个条目,更可能是几十个)。我想,我宁愿不使用内存数据库来处理如此小的数据集。

enter image description here

我想要完成的是能够快速查询基于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:表格需要修改(添加/删除)。

1 个答案:

答案 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的最终版本,因此不需要挥发物。