用于管理非重叠值范围的数据结构/算法?

时间:2017-09-22 21:24:04

标签: json algorithm data-structures binary-search-tree bitvector

我正在研究一个拥有成千上万个标志的系统。标志都是连续的数字,0到X,无论X最终是什么。 X预计会随着时间的推移而增长。而且我们期望拥有大量的用户。

我们主要关注的是:

  1. 能够快速测试用户是否设置了任何给定的标志。
  2. 能够快速设置旗帜。
  3. 能够将数据存储优化为尽可能小的尺寸。
  4. 使用10k标记,如果我们使用位向量,我们会在内存中查看每个用户大约1k的数据。哪个可能太多了。更糟糕的是,这是在Javascript中,存储在序列化为JSON的文档数据库中,这意味着我们有几个存储选项,其中没有一个我特别喜欢。

    1. 将标志存储为Uint32Array对象的JSON输出。看起来像是:"{"0":10,"1":4294967295}"。不幸的是,当标志接近其填充状态(占存储器的4倍以上)时,每4字节平均需要存储17个字节,并且在序列化时导致大约5k的存储器。这不太理想。
    2. 使用base64执行我们自己的JSON序列化,以避免数字 - 字符串方法的膨胀大小。不幸的是,这给JSON输入/输出阶段增加了一个额外的处理步骤,这使得事情变得复杂,因为现在我们必须在整个过程中修改我们的数据,并且会减慢一切。
    3. 所以...暂时搁置一下bitvector的想法。我想知道是否有更好的方法。我考虑过使用“数组范围”,例如:

      [{"m":0,"x":100},{"m":102},{"m":108,"x":204}]
      

      我们可以对这个系统中的数据做一些假设,这就是我采用这种方法的原因:

      1. 标志永远不会被取消。一旦设定,它将保持设定状态。
      2. 旗帜通常是聚集的。如果设置了标志X,那么X-1和X + 1也很有可能被设置。
      3. 标志通常设置为增加的索引值。如果正在设置标志X,那么X-1更可能被设置为比X + 1更高,并且很可能很快就会设置X + 1。
      4. 因此,由于这些条件,我认为存储范围对象数组可能是最佳解决方案。这样,随着时间的推移,用户的标志最终会缩小为一个大范围的条目。最佳情况当然是:

        [{"m":0,"x":10000}]
        

        最糟糕的情况当然是,如果他们以某种方式设法发现自己​​处于他们设置其他所有旗帜的状态。

        [{"m":0},{"m":2},{"m":4},{"m":6},{"m":8},{"m":10}...{"m":10000}]
        

        那会很糟糕。我认为,比bitvector解决方案要糟糕得多。但我们非常有信心不会发生这种情况。

        因此,关于快速决定是否设置标志的能力;这只是一个O(logn)二进制搜索(因为数组将被排序);只需找到最接近您的号码的范围对象,检查您的号码是否在该范围内,然后返回。

        插入更棘手。它仍然是二进制搜索,但现在我们正在修改数组。

        1. 一个相邻的兄弟插入:最佳方案。我们找到一个范围,其中min或max与我们插入的数字相差一个,并且只是递减或递增当前范围的值。 O(1)
        2. 没有相邻的兄弟插入:只需插入一个带有min set的新节点。 O(n),因为我们将向下移动数组中的所有内容。
        3. 两个相邻的兄弟插入:将最大值更改为右侧兄弟范围的最大值,从阵列中删除右侧兄弟范围并将其后的所有内容移到左侧。上)。
        4. 所以案例2 + 3让我想知道我是否应该尝试使用某种平衡的二叉搜索树。例如,一棵红黑树。

          值得这么麻烦吗?我是否想过这个?

0 个答案:

没有答案