I have one that I created for Swift on OS X which uses libdispatch to protect 
access to the underlying data:

/* dictionary that allows thread safe concurrent access */
final class ConcurrentDictionary<KeyType:Hashable,ValueType> : NSObject, 
SequenceType, DictionaryLiteralConvertible {
/* internal dictionary */
private var internalDictionary : [KeyType:ValueType]

/* queue modfications using a barrier and allow concurrent read operations */
private let queue = dispatch_queue_create( "dictionary access", 
DISPATCH_QUEUE_CONCURRENT )


/* count of key-value pairs in this dicitionary */
var count : Int {
var count = 0
dispatch_sync(self.queue) { () -> Void in
count = self.internalDictionary.count
}
return count
}


// safely get or set a copy of the internal dictionary value
var dictionary : [KeyType:ValueType] {
get {
var dictionaryCopy : [KeyType:ValueType]?
dispatch_sync(self.queue) { () -> Void in
dictionaryCopy = self.dictionary
}
return dictionaryCopy!
}

set {
let dictionaryCopy = newValue // create a local copy on the current thread
dispatch_async(self.queue) { () -> Void in
self.internalDictionary = dictionaryCopy
}
}
}


/* initialize an empty dictionary */
override convenience init() {
self.init( dictionary: [KeyType:ValueType]() )
}


/* allow a concurrent dictionary to be initialized using a dictionary literal 
of form: [key1:value1, key2:value2, ...] */
convenience required init(dictionaryLiteral elements: (KeyType, ValueType)...) {
var dictionary = Dictionary<KeyType,ValueType>()

for (key,value) in elements {
dictionary[key] = value
}

self.init(dictionary: dictionary)
}


/* initialize a concurrent dictionary from a copy of a standard dictionary */
init( dictionary: [KeyType:ValueType] ) {
self.internalDictionary = dictionary
}


/* provide subscript accessors */
subscript(key: KeyType) -> ValueType? {
get {
var value : ValueType?
dispatch_sync(self.queue) { () -> Void in
value = self.internalDictionary[key]
}
return value
}

set {
setValue(newValue, forKey: key)
}
}


/* assign the specified value to the specified key */
func setValue(value: ValueType?, forKey key: KeyType) {
// need to synchronize writes for consistent modifications
dispatch_barrier_async(self.queue) { () -> Void in
self.internalDictionary[key] = value
}
}


/* remove the value associated with the specified key and return its value if 
any */
func removeValueForKey(key: KeyType) -> ValueType? {
var oldValue : ValueType? = nil
// need to synchronize removal for consistent modifications
dispatch_barrier_sync(self.queue) { () -> Void in
oldValue = self.internalDictionary.removeValueForKey(key)
}
return oldValue
}


/* Generator of key-value pairs suitable for for-in loops */
func generate() -> Dictionary<KeyType,ValueType>.Generator {
var generator : Dictionary<KeyType,ValueType>.Generator!
dispatch_sync(self.queue) { () -> Void in
generator = self.internalDictionary.generate()
}
return generator
}
}

_____________________________________________________________________________________
Thomas Pelaia II, Ph.D.  | Applications Leader, Accelerator Physics, Research 
Accelerator Division
Spallation Neutron Source  |  Oak Ridge National Lab, Building 8600, MS-6462, 
Oak Ridge, TN 37831
phone: (865) 414-7960  | FaceTime: t...@ornl.gov<mailto:t...@ornl.gov> |  fax: 
(865) 574-6617  |  homepage: http://www.ornl.gov/~t6p

On Dec 10, 2015, at 12:18 PM, swift-users 
<swift-users@swift.org<mailto:swift-users@swift.org>> wrote:

Hi,

I'm writing some code where I'd like multiple threads to be writing to a common 
dictionary object.

Is there a recommended mechanism for doing this?

Thanks,
Lane

 _______________________________________________
swift-users mailing list
swift-users@swift.org<mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to