2016-08-30 21:44:58 +03:00
|
|
|
/**
|
|
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
|
|
* See LICENSE
|
|
|
|
*/
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
extension NSURL {
|
2016-09-07 21:12:18 +03:00
|
|
|
|
|
|
|
func parent(ofUrl url: NSURL) -> Bool {
|
|
|
|
guard self.fileURL && url.fileURL else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
let myPathComps = self.pathComponents!
|
|
|
|
let targetPathComps = url.pathComponents!
|
|
|
|
|
|
|
|
guard targetPathComps.count > myPathComps.count else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return Array(targetPathComps[0..<myPathComps.count]) == myPathComps
|
|
|
|
}
|
2016-08-30 21:44:58 +03:00
|
|
|
|
|
|
|
/// Wrapper function for NSURL.getResourceValue for Bool values.
|
|
|
|
/// Returns also `false` when
|
|
|
|
/// - there is no value for the given `key` or
|
|
|
|
/// - the value cannot be converted to `NSNumber`.
|
|
|
|
///
|
|
|
|
/// - parameters:
|
|
|
|
/// - key: The `key`-parameter of `NSURL.getResourceValue`.
|
|
|
|
func resourceValue(key: String) -> Bool {
|
|
|
|
var rsrc: AnyObject?
|
|
|
|
|
|
|
|
do {
|
|
|
|
try self.getResourceValue(&rsrc, forKey: key)
|
|
|
|
} catch {
|
|
|
|
// FIXME error handling
|
|
|
|
print("\(#function): \(self) -> ERROR while getting \(key)")
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if let result = rsrc as? NSNumber {
|
|
|
|
return result.boolValue
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
var dir: Bool {
|
|
|
|
return self.resourceValue(NSURLIsDirectoryKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
var hidden: Bool {
|
|
|
|
return self.resourceValue(NSURLIsHiddenKey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Array {
|
|
|
|
|
|
|
|
/// Concurrent and chunked version of `Array.map`.
|
|
|
|
///
|
|
|
|
/// - parameters:
|
|
|
|
/// - chunk: Batch size; defaults to `100`.
|
|
|
|
/// - queue: Defaults to `dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)`.
|
|
|
|
/// - transform: The transform function.
|
|
|
|
/// - returns: Transformed array of `self`.
|
|
|
|
func concurrentChunkMap<R>(
|
|
|
|
chunk: Int = 100,
|
|
|
|
queue: dispatch_queue_t = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
|
|
|
|
transform: (Element) -> R) -> [R]
|
|
|
|
{
|
|
|
|
let count = self.count
|
|
|
|
|
|
|
|
let chunkedCount = Int(ceil(Float(count) / Float(chunk)))
|
|
|
|
var result: [[R]] = []
|
|
|
|
|
2016-09-06 19:45:15 +03:00
|
|
|
var spinLock = OS_SPINLOCK_INIT
|
|
|
|
|
2016-08-30 21:44:58 +03:00
|
|
|
dispatch_apply(chunkedCount, queue) { idx in
|
|
|
|
let startIndex = min(idx * chunk, count)
|
|
|
|
let endIndex = min(startIndex + chunk, count)
|
|
|
|
|
|
|
|
let mappedChunk = self[startIndex..<endIndex].map(transform)
|
2016-09-06 19:45:15 +03:00
|
|
|
|
|
|
|
OSSpinLockLock(&spinLock)
|
|
|
|
result.append(mappedChunk)
|
|
|
|
OSSpinLockUnlock(&spinLock)
|
2016-08-30 21:44:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return result.flatMap { $0 }
|
|
|
|
}
|
|
|
|
}
|