事务队列的数据结构

时间:2011-03-15 09:47:14

标签: .net algorithm data-structures transactions queue

对于事务队列,是否存在比使用List更合适/更有效的数据结构。我已经尝试过使用队列和堆栈,但两者都没有正确地适应账单。

我在下面详细介绍了我的问题,并举例说明了为什么我暂时最终得到了一个List。任何关于替代数据结构的建议(最好但不限于那些在.Net BCL中实现的建议)都表示赞赏。

问题

维护Insert() / Delete()个操作的事务队列,稍后当用户调用Commit()方法时将其保留到任意后备存储,或者在调用{{1}时丢弃方法。

必须对受影响对象的内存中状态执行操作,因为后续操作可能依赖于先前操作创建的对象的状态。

示例1

我有一个对象Rollback(),它以空集合开头。用户插入项obj,然后删除项i

然后他们调用i,给定队列的以下数据结构,在回滚中发生以下情况:

  • 队列 - Rollback()obj.Delete(i) - >不正确,因为obj.Insert(i)在回滚后应保持为空
  • 堆叠 - objobj.Insert(i) - >正确,因为obj.Delete(i)仍为空
  • 列表(反向遍历) - objobj.Insert(i) - >正确,因为obj.Delete(i)仍为空

如果他们拨打obj,则会发生以下情况:

  • 队列 - Commit()obj.Insert(i) - >正确,因为obj.Delete(i)仍为空
  • 堆叠 - objobj.Delete(i) - >不正确,因为obj.Insert(i)不为空
  • 列表(正向遍历) - objobj.Insert(i) - >正确,因为obj.Delete(i)仍为空

因此,对于此示例,队列适用于obj但不适用于Commit(),而堆栈显示反向行为两者都不正确。只有列表显示正确的行为,但请注意,对于提交,我们以正向方向遍历列表,而对于回滚,我们以反方向遍历列表。

示例2

现在考虑再次使用一个对象Rollback(),这次以包含在其中的单个项目obj开头。

这次操作的顺序是删除i,然后插入i

如果他们致电i,则会发生以下情况:

  • 队列 - Rollback()obj.Insert(i) - >不正确,因为obj.Delete(i)最终为空
  • 堆叠 - objobj.Delete(i) - >正确,因为obj.Insert(i)包含单个项obj仍然
  • 列表(反向遍历) - iobj.Delete(i) - >正确,因为obj.Insert(i)包含单个项obj仍然

如果他们改为呼叫i,则会发生以下情况:

  • 队列 - Commit()obj.Delete(i) - >正确,因为obj.Insert(i)包含单个项obj仍然
  • 堆叠 - iobj.Insert(i) - >不正确,因为obj.Delete(i)最终为空
  • 列表(正向遍历) - objobj.Delete(i) - >正确,因为obj.Insert(i)包含单个项obj仍然

与前面的示例一样,在这两种情况下只使用List是正确的,但我们必须根据我们是提交还是回滚来在不同的方向上遍历它。

底线

虽然使用List本身并不低效,但我只是想知道是否有更合适的数据结构更适合我的问题?

1 个答案:

答案 0 :(得分:1)

从技术上讲,您可以使用LinkedList<T>。这就像Queue + Stack:你可以从头部和尾部添加和删除,在两种情况下它都是O(1)(但它通常比List慢,原因是连接到内存局部性并且需要为每次添加元素分配内存)

(请不要杀我,因为我说LinkedList<T>就像Queue + Stack ...我知道差异......我的意思只是它可以是同时用于两种方式)

我要补充一点,如果您认为Rollback是“例外”(很少见),那么您可以使用Queue,当您拥有Rollback时{} 1}}使用LINQ的Reverse的输出。作为一个“例外”,它可能会更慢(你甚至不需要LINQ ......你可以做Queue并以相反的顺序遍历数组)