-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
AntonioL
committed
Jan 11, 2017
0 parents
commit 18e7a04
Showing
2 changed files
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Wait-Free Union Find | ||
|
||
This is a my own implementation of a bounded wait-free concurrent union-find data structure. | ||
|
||
The implementation follows the paper [1]. | ||
|
||
It is implemented in Scala to avoid the verbosity of the Java programming language. | ||
|
||
|
||
## References | ||
|
||
[1] Anderson, Richard J., and Heather Woll. "Wait-free parallel algorithms for the union-find problem." Proceedings of the twenty-third annual ACM symposium on Theory of computing. ACM, 1991. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import java.util.concurrent.atomic.{AtomicReferenceArray, AtomicInteger} | ||
class WFUnionFind (size : Int) { | ||
|
||
private class Node (val dummyNext : Int, val rank : Int) { | ||
private val container = new AtomicInteger(dummyNext) | ||
def next = container.get | ||
def casNext(old : Int, newValue : Int) = container.compareAndSet(old, newValue) | ||
} | ||
|
||
private val array = new AtomicReferenceArray[Node](Array.tabulate(size)(i => new Node(i, 0))) | ||
|
||
private def updateRoot(x : Int, oldRank : Int, y : Int, newRank : Int) : Boolean = { | ||
val old = array.get(x) | ||
if(old.next != x || old.rank != oldRank) { | ||
return false | ||
} | ||
val newNode = new Node(y, newRank) | ||
return array.compareAndSet(x, old, newNode) | ||
} | ||
|
||
private def find(idx : Int) : Int = { | ||
var (x, node) = (idx, array.get(idx)) | ||
while(x != node.next) { | ||
val t = node.next | ||
val tNode = array.get(t) | ||
node.casNext(t, tNode.next) | ||
x = t; node = tNode; | ||
} | ||
return x | ||
} | ||
|
||
def sameSet(x : Int, y : Int) : Boolean = { | ||
while(true) { | ||
val (set_x, set_y) = (find(x), find(y)) | ||
if(set_x == set_y) { | ||
return true | ||
} else if(array.get(set_x).next == set_x) { | ||
return false | ||
} | ||
} | ||
sys.error("Never reach here") | ||
} | ||
|
||
def union(x : Int, y : Int) : Unit = { | ||
while(true) { | ||
var set_x = find(x); var set_y = find(y) | ||
if(set_x == set_y) return | ||
var set_x_rank = array.get(set_x).rank | ||
var set_y_rank = array.get(set_y).rank | ||
if(set_x_rank > set_y_rank || (set_x_rank == set_y_rank && set_x > set_y)) { | ||
val (t1, t2) = (set_x, set_x_rank) | ||
set_x = set_y; set_x_rank = set_y_rank | ||
set_y = t1; set_y_rank = t2 | ||
} | ||
if(updateRoot(set_x, set_x_rank, set_y, set_x_rank)) { | ||
if(set_x_rank == set_y_rank) { | ||
updateRoot(set_y, set_y_rank, set_y, set_y_rank + 1) | ||
} | ||
return | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
} |