forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dictionary.swift
128 lines (112 loc) · 2.61 KB
/
Dictionary.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
class DictionaryStringInt : Enumerable {
var strings : String[]
var ints : Int[]
var taken : UInt8[]
var size : Int
constructor(bc : Int = 127) {
strings = new String[bc]
ints = new Int[bc]
taken = new UInt8[bc]
}
func getBucketCount() -> Int {
return strings.length
}
func add(s : String, i : Int) -> Bool {
var h : UInt = s.hash()
var index : Int = Int(h % UInt(strings.length))
var count = 0
while (taken[index] == 1 && strings[index] != s)
{
++index
if index == taken.length {
index = 0
}
++count
if count == taken.length {
return false
}
}
strings[index] = s
ints[index] = i
if taken[index] == 0 {
++size
}
taken[index] = 1
return true
}
func find(s : String) -> (Bool, Int) {
var h : UInt = s.hash()
var index : Int = Int(h % UInt(strings.length))
var count = 0
while (taken[index] == 0 || strings[index] != s)
{
++index
if index == taken.length {
index = 0
}
++count
if count == taken.length {
return (false, 0)
}
}
return (true, ints[index])
}
subscript (s : String) -> Int {
get {
var t : (found : Bool, i : Int) = find(s)
if t.found {
return t.i
}
add(s, 0)
return 0
}
set {
add(s, value)
}
}
// Enumerable
typealias Elements = DictionaryStringIntRange
func getElements() -> Elements {
return DictionaryStringIntRange(this)
}
}
struct DictionaryStringIntRange : Range {
var dict : DictionaryStringInt
var count : Int
constructor(v : DictionaryStringInt) {
dict = v
}
typealias Element = (key : String, value : Int)
func isEmpty() -> Bool {
return dict.size == 0 || count == dict.getBucketCount()
}
func getFirstAndAdvance() -> Element {
while count != dict.getBucketCount() && dict.taken[count] == 0 {
++count
}
var e : Element
e = (dict.strings[count], dict.ints[count])
++count
while count != dict.getBucketCount() && dict.taken[count] == 0 {
++count
}
return e
}
}
// FIXME: Define an item type because we can't create arrays of tuples.
struct DictionaryStringIntItem {
var key : String
var value : Int
}
extension DictionaryStringInt {
func itemsAsArray() -> DictionaryStringIntItem[] {
var result = new DictionaryStringIntItem[size]
var index = 0
for i in 0..getBucketCount() {
if (taken[i] == 0) { continue }
result[index] = DictionaryStringIntItem(strings[i], ints[i])
++index
}
return result
}
}