github.com/whatap/golib@v0.0.22/util/hmap/IntSet.go (about) 1 package hmap 2 3 import ( 4 "bytes" 5 "fmt" 6 "sync" 7 "strconv" 8 ) 9 10 // TODO SearchPathMap 에서 사용하기 위해 생성 (현재는 생성만) 11 // 테스트 필요. 12 type IntSet struct { 13 table []*IntSetry 14 count int 15 threshold int 16 loadFactor float32 17 lock sync.Mutex 18 max int 19 } 20 21 func NewIntSet() *IntSet { 22 23 initCapacity := DEFAULT_CAPACITY 24 loadFactor := DEFAULT_LOAD_FACTOR 25 26 this := new(IntSet) 27 this.loadFactor = float32(loadFactor) 28 this.table = make([]*IntSetry, initCapacity) 29 this.threshold = int(float64(initCapacity) * loadFactor) 30 return this 31 } 32 33 func NewIntSetArray(arr []string) *IntSet { 34 35 initCapacity := DEFAULT_CAPACITY 36 loadFactor := DEFAULT_LOAD_FACTOR 37 38 this := new(IntSet) 39 this.loadFactor = float32(loadFactor) 40 this.table = make([]*IntSetry, initCapacity) 41 this.threshold = int(float64(initCapacity) * loadFactor) 42 return this 43 } 44 45 func (this *IntSet) Size() int { 46 return this.count 47 } 48 49 func (this *IntSet) Values() *IntSetEnumer { 50 return &IntSetEnumer{table: this.table, index: len(this.table), entry: nil} 51 } 52 53 func (this *IntSet) Contains(key int32) bool { 54 this.lock.Lock() 55 defer this.lock.Unlock() 56 tab := this.table 57 index := uint(key) % uint(len(tab)) 58 for e := tab[index]; e != nil; e = e.next { 59 if e.key == key { 60 return true 61 } 62 } 63 return false 64 } 65 66 func (this *IntSet) rehash() { 67 oldCapacity := len(this.table) 68 oldMap := this.table 69 newCapacity := oldCapacity*2 + 1 70 newMap := make([]*IntSetry, newCapacity) 71 this.threshold = int(float32(newCapacity) * this.loadFactor) 72 this.table = newMap 73 for i := oldCapacity; i > 0; i-- { 74 for old := oldMap[i-1]; old != nil; { 75 e := old 76 old = old.next 77 index := uint(e.key) % uint(newCapacity) 78 e.next = newMap[index] 79 newMap[index] = e 80 } 81 } 82 } 83 84 func (this *IntSet) PutAll(values []int32) { 85 if values == nil { 86 return 87 } 88 ln := len(values) 89 for i := 0; i < ln; i++ { 90 this.Put(values[i]) 91 } 92 } 93 94 func (this *IntSet) Put(key int32) bool { 95 this.lock.Lock() 96 defer this.lock.Unlock() 97 return this.put(key) 98 } 99 100 func (this *IntSet) put(value int32) bool { 101 tab := this.table 102 index := uint(value) % uint(len(tab)) 103 for e := tab[index]; e != nil; e = e.next { 104 if e.key == value { 105 return false 106 } 107 } 108 if this.count >= this.threshold { 109 this.rehash() 110 tab = this.table 111 index = uint(value) % uint(len(tab)) 112 } 113 e := &IntSetry{key: value, next: tab[index]} 114 tab[index] = e 115 this.count++ 116 return true 117 } 118 119 func (this *IntSet) Remove(key int32) int32 { 120 this.lock.Lock() 121 defer this.lock.Unlock() 122 123 return this.remove(key) 124 } 125 126 func (this *IntSet) remove(key int32) int32 { 127 tab := this.table 128 index := uint(key) % uint(len(tab)) 129 e := tab[index] 130 var prev *IntSetry = nil 131 for e != nil { 132 if e.key == key { 133 if prev != nil { 134 prev.next = e.next 135 } else { 136 tab[index] = e.next 137 } 138 this.count-- 139 return key 140 } 141 prev = e 142 e = e.next 143 } 144 return 0 145 } 146 147 func (this *IntSet) Clear() { 148 this.lock.Lock() 149 defer this.lock.Unlock() 150 this.clear() 151 } 152 func (this *IntSet) clear() { 153 tab := this.table 154 for index := len(tab) - 1; index >= 0; index-- { 155 tab[index] = nil 156 } 157 this.count = 0 158 } 159 160 func (this *IntSet) ToString() string { 161 this.lock.Lock() 162 defer this.lock.Unlock() 163 return this.toString() 164 } 165 166 func (this *IntSet) toString() string { 167 max := this.Size() - 1 168 169 var buf bytes.Buffer 170 171 it := this.Values() 172 buf.WriteString("{") 173 174 for i := 0; i <= max; i++ { 175 key := it.NextInt() 176 buf.WriteString(strconv.Itoa(int(key))) 177 178 if i < max { 179 buf.WriteString(", ") 180 } 181 } 182 183 buf.WriteString("}") 184 return buf.String() 185 } 186 187 //public static IntEnumer emptyEnumer = new IntEnumer() { 188 // public int nextInt() { 189 // return 0; 190 // } 191 // 192 // public boolean hasMoreElements() { 193 // return false; 194 // } 195 // }; 196 197 type IntSetEnumer struct { 198 table []*IntSetry 199 index int 200 entry *IntSetry 201 } 202 203 func NewIntSetEnumer(table []*IntSetry, index int) { 204 p := new(IntSetEnumer) 205 p.table = table 206 p.index = len(table) 207 p.entry = nil 208 } 209 func (this *IntSetEnumer) HasMoreElements() bool { 210 for this.entry == nil && this.index > 0 { 211 this.index-- 212 this.entry = this.table[this.index] 213 } 214 return this.entry != nil 215 } 216 217 func (this *IntSetEnumer) NextInt() int32 { 218 for this.entry == nil && this.index > 0 { 219 this.index-- 220 this.entry = this.table[this.index] 221 } 222 if this.entry != nil { 223 e := this.entry 224 this.entry = e.next 225 return e.key 226 } 227 //panic("no more next") 228 return 0 229 } 230 231 func IntSetMain() { 232 s := NewIntSet() 233 s.Put(111) 234 s.Put(2222) 235 s.Put(3333) 236 // s.Sort(c func(k1, k2 string) bool) 237 fmt.Println(s) 238 // s.Sort(false) 239 fmt.Println(s) 240 }