【问题标题】:Scala mutable versioned collection, retaining change historyScala 可变版本集合,保留更改历史
【发布时间】:2015-12-15 13:33:55
【问题描述】:

我正在寻找:

  1. 类似于键值映射的可变集合的接口,它将以某种方式保留单个元素的先前状态,即可以获取已知其键的元素的所有先前和当前状态。
  2. 此类接口的实现,最好在某种数据库或其他一些持久性存储中提供支持。

Slick 数据库访问工具包确实允许像访问常规 Scala 集合一样访问 SQL 数据库,但是,它不包括访问集合中条目的任何历史状态。例如,您可以这样做:

suppliers(42)     // => gets current state of a supplier with ID=42
suppliers.get(42) // => gets current state or None if not found

但您无法获得所有先前状态的列表,也无法通过某种历史 ID 获得特定的历史状态。我浏览过Scala collection overview,似乎他们都没有提供这样的API。符合Map[T] 接口的所有内容在获取元素时仅返回单个(最新、当前)值T

这个概念在多个数据库后端实现,例如:

其他语言也有不少现成的解决方案,例如:

【问题讨论】:

  • 是否也可以使用其他后端(或仅标签中的后端)?
  • @Beryllium 绝对有可能,它更多的是寻找标准接口而不是单一的现成解决方案。

标签: mongodb scala collections cassandra couchdb


【解决方案1】:

听起来您有一个简单的库,但特别是因为您提到对数据库具有持久性,我认为您将需要比标准库数据结构更重量级的东西。

我建议查看Akka Persistence。我需要一些时间来编写一个示例,但基本上你启动一个ActorSystem,启动你的持久历史地图actor,然后使用ask pattern 来查询你的actor。 Akka Persistence 可以轻松配置为将其日志持久保存到 datastore of your choice

如果您真的不需要内置持久性,则可以扩展 mutable map trait。以下内容尚未经过测试,但它应该像一个基本的可变地图一样,同时在内部存储历史记录。不确定-= 的语义相对于该历史应该是什么,所以只是做了一个假设。给你:

class MutableHistoryMap[K, V] extends scala.collection.mutable.Map[K, V] {
  // Invariant: if a key exists, the sequence it maps to has at least one item
  val internalMap = scala.collection.mutable.Map[K, Seq[V]]()

  def +=(kv: (K, V)): MutableHistoryMap.this.type = {
    val (key, newValue) = kv
    val oldValues = internalMap.get(key).getOrElse(Seq())
    internalMap.update(key, newValue +: oldValues)
    this
  }

  def -=(key: K): MutableHistoryMap.this.type = {
    internalMap.get(key) match {
      case Some(values) if values.size > 1=> 
        internalMap.update(key, values.tail)
      case _ =>
        internalMap -= key
    }
    this
  }

  def get(key: K): Option[V] = 
    internalMap.get(key).flatMap(_.headOption)

  def iterator: Iterator[(K, V)] = 
    internalMap.iterator.map {
      case (key, values) => (key, values.head)
    }

  // then whatever methods for modifying your history
}

【讨论】:

    猜你喜欢
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 2010-11-02
    相关资源
    最近更新 更多