//TODO:
class Book {
let author:String;
let title:String;
let stockNumber:Int;
var reader:String?
var checkoutCount = 0;
init(author:String, title:String, stock:Int) {
self.author = author;
self.title = title;
self.stockNumber = stock;
}
}
import Foundation
final class Library {
private let books:[Book];
private let pool:Pool<Book>;
private init(stockLevel:Int) {
books = [Book]();
for count in 1 ... stockLevel {
books.append(Book(author: "Dickens, Charles", title: "Hard Times",
stock: count))
}
pool = Pool<Book>(items:books);
}
private class var singleton:Library {
struct SingletonWrapper {
static let singleton = Library(stockLevel:2);
}
return SingletonWrapper.singleton;
}
class func checkoutBook(reader:String) -> Book? {
var book = singleton.pool.getFromPool();
book?.reader = reader;
book?.checkoutCount++;
return book;
}
class func returnBook(book:Book) {
book.reader = nil;
singleton.pool.returnToPool(book);
}
class func printReport() {
for book in singleton.books {
println("...Book#\(book.stockNumber)...");
println("Checked out \(book.checkoutCount) times");
if (book.reader != nil) {
println("Checked out to \(book.reader!)");
} else {
println("In stock");
}
}
}
}
import Foundation
class Pool<T> {
private var data = [T]();
private let arrayQ = dispatch_queue_create("arrayQ", DISPATCH_QUEUE_SERIAL);
private let semaphore:dispatch_semaphore_t;
init(items:[T]) {
data.reserveCapacity(data.count);
for item in items {
data.append(item);
}
semaphore = dispatch_semaphore_create(items.count);
}
func getFromPool() -> T? {
var result:T?;
if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) == 0) {
dispatch_sync(arrayQ, {() in
result = self.data.removeAtIndex(0);
})
}
return result;
}
func returnToPool(item:T) {
dispatch_async(arrayQ, {() in
self.data.append(item);
dispatch_semaphore_signal(self.semaphore);
});
}
}