Scala :: PriorityQueue => 更新特定项目的优先级
Posted
技术标签:
【中文标题】Scala :: PriorityQueue => 更新特定项目的优先级【英文标题】:Scala :: PriorityQueue => update priority of specific item 【发布时间】:2012-08-28 10:09:39 【问题描述】:我已经实现了从头部提取项目的例程,更新它的优先级并使用这样的非阻塞方法将其放回队列(使用 AtomicReference)
def head(): Entry =
def takeAndUpdate(e: Entry, success: Boolean): Entry =
if (success)
return e
val oldQueue = queueReference.get()
val newQueue = oldQueue.clone()
val item = newQueue.dequeue().increase()
newQueue += item
takeAndUpdate(item.e, queueReference.compareAndSet(oldQueue, newQueue))
takeAndUpdate(null, false)
现在我需要找出队列中的任意条目,更改它的优先级并将其放回队列。 PriorityQueue 似乎不支持这一点,那么我应该使用哪个类来完成所需的行为?
与Change priority of items in a priority queue有关
【问题讨论】:
您是否尝试过使用不同的方法:例如SortedSet
(或SortedMap
)?
@oxbow_lakes 现在我正在尝试用 TreeSet 实现它
你没有定义上面的load
是什么。
【参考方案1】:
使用不可变的树形图 (immutable.TreeMap
) 来完成此操作。您必须以某种方式找到所需的条目 - 最好的方法是将用于查找条目的部分信息 (Key
) 与键关联,以及您希望返回的实际条目与值在地图中(称之为Entry
)。
将queueReference
重命名为treeReference
。在您创建集合的代码部分,使用immutable.TreeMap[Key, Entry](<list of elements>)
。
然后像这样修改代码:
def updateKey(k: Key)
@annotation.tailrec def update(): (Key, Entry) =
val oldTree = treeReference.get()
val entry = oldTree(k)
val newPair = modifyHoweverYouWish(k, entry)
val newTree = (oldTree - k) + newPair
if (treeReference.compareAndSet(oldTree, newTree)) newPair
else update()
update()
如果compareAndSet
失败,您必须像在源代码中所做的那样重复。最好使用@tailrec
,如上图,保证函数是尾递归的,防止潜在的堆栈溢出。
或者,您可以使用immutable.TreeSet
- 如果您知道对您的Entry
对象的确切引用,您可以使用它通过上面的-
删除元素,然后在调用increase()
后将其添加回来.代码几乎一样。
【讨论】:
以上是关于Scala :: PriorityQueue => 更新特定项目的优先级的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 PriorityQueue (Scala) 的隐式排序时遇到问题
scala.collection.mutable.PriorityQueue:与案例类的 2 个或更多属性进行比较
Scala 问题对 Stack[A] 使用 PriorityQueue 非默认排序