     var decreaseBuckets: Bool = true { didSet { if decreaseBuckets && (!oldValue || !resetBuckets) { resetBuckets = true } } }
     var increaseBuckets: Bool = true { didSet { if increaseBuckets && (!oldValue || !resetBuckets) { resetBuckets = true } } }
     
-    init(_ f: K -> Int) {
-        self.hashFunction = f
-    }
-    
-    init(_ array: [(key: K, value: V)]) throws {
-        self.init(array.count >> 2)
+    init(_ array: [(key: K, value: V)], buckets: Int = 0x10) throws {
+        self.init(buckets: buckets, resetBuckets: false)
         try insert(array)
     }
     
-    init(_ array: [(key: K, value: V)], buckets: Int) throws {
-        self.init(buckets, resetBuckets: false)
-        try insert(array)
-    }
-    
-    init() {}
-    
-    init(_ buckets: Int, resetBuckets: Bool) {
-        table = [[(key: K, value: V)]](count: buckets, repeatedValue: [])
-    }
-    
-    init(_ buckets : Int) { // convenience init
-        self.init(_: buckets, resetBuckets: false)
-    }
-    
-    init(_ buckets : Int, hashFunction: K -> Int) {
-        self.init(buckets, hashFunction: hashFunction, resetBuckets: false)
-    }
-    
-    init(_ buckets : Int, hashFunction: K -> Int, resetBuckets: Bool) {
-        table = [[(key: K, value: V)]](count: buckets, repeatedValue: [])
+    init(buckets: Int = 0x10, resetBuckets: Bool = true, hashFunction: K -> Int = { $0.hashValue }) {
+        table = [[(key: K, value: V)]](count: buckets.nextPowerOf2, repeatedValue: [])
         self.hashFunction = hashFunction
         self.resetBuckets = resetBuckets
     }
     
     //P.ERFORMANCE maybe in parallel or hashing all first in parallel, then appending all?
-    mutating func insert(elements: (key: K, value: V)...) throws {
+    mutating func insert(elements elements: (key: K, value: V)...) throws {
         try insert(elements)
     }
     
     //P.ERFORMANCE maybe in parallel or hashing all first in parallel, then appending all?
     mutating func insert(elements: [(key: K, value: V)]) throws {
         try correctBucketCount(count + elements.count)
-        print("inserting " + elements.count + " elements.")
+        let oldResetBuckets = resetBuckets
+        self.resetBuckets = false
         for v in elements {
-            // print("inserting " + new)
-            try insert(v)
+            try insert(element: v)
         }
         print("tries to correct in \(#function)")
+        self.resetBuckets = oldResetBuckets
         try correctBucketCount()
     }
     

import Foundation


protocol HashTableElementType {
    associatedtype Element
    init(elem: Element)
    var key : Int { get }
    var elem : Element { get }
    var hashValue : Int { get }
}
extension HashTableElementType {
    var hashValue : Int { return key }
}

struct HashTable <K: Hashable, V> : ArrayLiteralConvertible, CustomStringConvertible {

        // => buckets * 16 >= count
        // count > buckets / 16
        let minBuckets = 4
        let LOGmaxBucketSize = Int(log2(Double(maxBucketSize)))
        // => maxBucketSize = 2 ^ (LOGmaxBucketSize)
        // => bucketSize between 2^(x-1) and 2^(x)
        // x = 4 => bucketSize between 4 and 8
