github.com/gogf/gf/v2@v2.7.4/container/gmap/gmap_hash_any_any_map.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with gm file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gmap 8 9 import ( 10 "github.com/gogf/gf/v2/container/gvar" 11 "github.com/gogf/gf/v2/internal/deepcopy" 12 "github.com/gogf/gf/v2/internal/empty" 13 "github.com/gogf/gf/v2/internal/json" 14 "github.com/gogf/gf/v2/internal/rwmutex" 15 "github.com/gogf/gf/v2/util/gconv" 16 "reflect" 17 ) 18 19 // AnyAnyMap wraps map type `map[interface{}]interface{}` and provides more map features. 20 type AnyAnyMap struct { 21 mu rwmutex.RWMutex 22 data map[interface{}]interface{} 23 } 24 25 // NewAnyAnyMap creates and returns an empty hash map. 26 // The parameter `safe` is used to specify whether using map in concurrent-safety, 27 // which is false in default. 28 func NewAnyAnyMap(safe ...bool) *AnyAnyMap { 29 return &AnyAnyMap{ 30 mu: rwmutex.Create(safe...), 31 data: make(map[interface{}]interface{}), 32 } 33 } 34 35 // NewAnyAnyMapFrom creates and returns a hash map from given map `data`. 36 // Note that, the param `data` map will be set as the underlying data map(no deep copy), 37 // there might be some concurrent-safe issues when changing the map outside. 38 func NewAnyAnyMapFrom(data map[interface{}]interface{}, safe ...bool) *AnyAnyMap { 39 return &AnyAnyMap{ 40 mu: rwmutex.Create(safe...), 41 data: data, 42 } 43 } 44 45 // Iterator iterates the hash map readonly with custom callback function `f`. 46 // If `f` returns true, then it continues iterating; or false to stop. 47 func (m *AnyAnyMap) Iterator(f func(k interface{}, v interface{}) bool) { 48 for k, v := range m.Map() { 49 if !f(k, v) { 50 break 51 } 52 } 53 } 54 55 // Clone returns a new hash map with copy of current map data. 56 func (m *AnyAnyMap) Clone(safe ...bool) *AnyAnyMap { 57 return NewFrom(m.MapCopy(), safe...) 58 } 59 60 // Map returns the underlying data map. 61 // Note that, if it's in concurrent-safe usage, it returns a copy of underlying data, 62 // or else a pointer to the underlying data. 63 func (m *AnyAnyMap) Map() map[interface{}]interface{} { 64 m.mu.RLock() 65 defer m.mu.RUnlock() 66 if !m.mu.IsSafe() { 67 return m.data 68 } 69 data := make(map[interface{}]interface{}, len(m.data)) 70 for k, v := range m.data { 71 data[k] = v 72 } 73 return data 74 } 75 76 // MapCopy returns a shallow copy of the underlying data of the hash map. 77 func (m *AnyAnyMap) MapCopy() map[interface{}]interface{} { 78 m.mu.RLock() 79 defer m.mu.RUnlock() 80 data := make(map[interface{}]interface{}, len(m.data)) 81 for k, v := range m.data { 82 data[k] = v 83 } 84 return data 85 } 86 87 // MapStrAny returns a copy of the underlying data of the map as map[string]interface{}. 88 func (m *AnyAnyMap) MapStrAny() map[string]interface{} { 89 m.mu.RLock() 90 defer m.mu.RUnlock() 91 data := make(map[string]interface{}, len(m.data)) 92 for k, v := range m.data { 93 data[gconv.String(k)] = v 94 } 95 return data 96 } 97 98 // FilterEmpty deletes all key-value pair of which the value is empty. 99 // Values like: 0, nil, false, "", len(slice/map/chan) == 0 are considered empty. 100 func (m *AnyAnyMap) FilterEmpty() { 101 m.mu.Lock() 102 defer m.mu.Unlock() 103 for k, v := range m.data { 104 if empty.IsEmpty(v) { 105 delete(m.data, k) 106 } 107 } 108 } 109 110 // FilterNil deletes all key-value pair of which the value is nil. 111 func (m *AnyAnyMap) FilterNil() { 112 m.mu.Lock() 113 defer m.mu.Unlock() 114 for k, v := range m.data { 115 if empty.IsNil(v) { 116 delete(m.data, k) 117 } 118 } 119 } 120 121 // Set sets key-value to the hash map. 122 func (m *AnyAnyMap) Set(key interface{}, value interface{}) { 123 m.mu.Lock() 124 if m.data == nil { 125 m.data = make(map[interface{}]interface{}) 126 } 127 m.data[key] = value 128 m.mu.Unlock() 129 } 130 131 // Sets batch sets key-values to the hash map. 132 func (m *AnyAnyMap) Sets(data map[interface{}]interface{}) { 133 m.mu.Lock() 134 if m.data == nil { 135 m.data = data 136 } else { 137 for k, v := range data { 138 m.data[k] = v 139 } 140 } 141 m.mu.Unlock() 142 } 143 144 // Search searches the map with given `key`. 145 // Second return parameter `found` is true if key was found, otherwise false. 146 func (m *AnyAnyMap) Search(key interface{}) (value interface{}, found bool) { 147 m.mu.RLock() 148 if m.data != nil { 149 value, found = m.data[key] 150 } 151 m.mu.RUnlock() 152 return 153 } 154 155 // Get returns the value by given `key`. 156 func (m *AnyAnyMap) Get(key interface{}) (value interface{}) { 157 m.mu.RLock() 158 if m.data != nil { 159 value = m.data[key] 160 } 161 m.mu.RUnlock() 162 return 163 } 164 165 // Pop retrieves and deletes an item from the map. 166 func (m *AnyAnyMap) Pop() (key, value interface{}) { 167 m.mu.Lock() 168 defer m.mu.Unlock() 169 for key, value = range m.data { 170 delete(m.data, key) 171 return 172 } 173 return 174 } 175 176 // Pops retrieves and deletes `size` items from the map. 177 // It returns all items if size == -1. 178 func (m *AnyAnyMap) Pops(size int) map[interface{}]interface{} { 179 m.mu.Lock() 180 defer m.mu.Unlock() 181 if size > len(m.data) || size == -1 { 182 size = len(m.data) 183 } 184 if size == 0 { 185 return nil 186 } 187 var ( 188 index = 0 189 newMap = make(map[interface{}]interface{}, size) 190 ) 191 for k, v := range m.data { 192 delete(m.data, k) 193 newMap[k] = v 194 index++ 195 if index == size { 196 break 197 } 198 } 199 return newMap 200 } 201 202 // doSetWithLockCheck checks whether value of the key exists with mutex.Lock, 203 // if not exists, set value to the map with given `key`, 204 // or else just return the existing value. 205 // 206 // When setting value, if `value` is type of `func() interface {}`, 207 // it will be executed with mutex.Lock of the hash map, 208 // and its return value will be set to the map with `key`. 209 // 210 // It returns value with given `key`. 211 func (m *AnyAnyMap) doSetWithLockCheck(key interface{}, value interface{}) interface{} { 212 m.mu.Lock() 213 defer m.mu.Unlock() 214 if m.data == nil { 215 m.data = make(map[interface{}]interface{}) 216 } 217 if v, ok := m.data[key]; ok { 218 return v 219 } 220 if f, ok := value.(func() interface{}); ok { 221 value = f() 222 } 223 if value != nil { 224 m.data[key] = value 225 } 226 return value 227 } 228 229 // GetOrSet returns the value by key, 230 // or sets value with given `value` if it does not exist and then returns this value. 231 func (m *AnyAnyMap) GetOrSet(key interface{}, value interface{}) interface{} { 232 if v, ok := m.Search(key); !ok { 233 return m.doSetWithLockCheck(key, value) 234 } else { 235 return v 236 } 237 } 238 239 // GetOrSetFunc returns the value by key, 240 // or sets value with returned value of callback function `f` if it does not exist 241 // and then returns this value. 242 func (m *AnyAnyMap) GetOrSetFunc(key interface{}, f func() interface{}) interface{} { 243 if v, ok := m.Search(key); !ok { 244 return m.doSetWithLockCheck(key, f()) 245 } else { 246 return v 247 } 248 } 249 250 // GetOrSetFuncLock returns the value by key, 251 // or sets value with returned value of callback function `f` if it does not exist 252 // and then returns this value. 253 // 254 // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function `f` 255 // with mutex.Lock of the hash map. 256 func (m *AnyAnyMap) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} { 257 if v, ok := m.Search(key); !ok { 258 return m.doSetWithLockCheck(key, f) 259 } else { 260 return v 261 } 262 } 263 264 // GetVar returns a Var with the value by given `key`. 265 // The returned Var is un-concurrent safe. 266 func (m *AnyAnyMap) GetVar(key interface{}) *gvar.Var { 267 return gvar.New(m.Get(key)) 268 } 269 270 // GetVarOrSet returns a Var with result from GetOrSet. 271 // The returned Var is un-concurrent safe. 272 func (m *AnyAnyMap) GetVarOrSet(key interface{}, value interface{}) *gvar.Var { 273 return gvar.New(m.GetOrSet(key, value)) 274 } 275 276 // GetVarOrSetFunc returns a Var with result from GetOrSetFunc. 277 // The returned Var is un-concurrent safe. 278 func (m *AnyAnyMap) GetVarOrSetFunc(key interface{}, f func() interface{}) *gvar.Var { 279 return gvar.New(m.GetOrSetFunc(key, f)) 280 } 281 282 // GetVarOrSetFuncLock returns a Var with result from GetOrSetFuncLock. 283 // The returned Var is un-concurrent safe. 284 func (m *AnyAnyMap) GetVarOrSetFuncLock(key interface{}, f func() interface{}) *gvar.Var { 285 return gvar.New(m.GetOrSetFuncLock(key, f)) 286 } 287 288 // SetIfNotExist sets `value` to the map if the `key` does not exist, and then returns true. 289 // It returns false if `key` exists, and `value` would be ignored. 290 func (m *AnyAnyMap) SetIfNotExist(key interface{}, value interface{}) bool { 291 if !m.Contains(key) { 292 m.doSetWithLockCheck(key, value) 293 return true 294 } 295 return false 296 } 297 298 // SetIfNotExistFunc sets value with return value of callback function `f`, and then returns true. 299 // It returns false if `key` exists, and `value` would be ignored. 300 func (m *AnyAnyMap) SetIfNotExistFunc(key interface{}, f func() interface{}) bool { 301 if !m.Contains(key) { 302 m.doSetWithLockCheck(key, f()) 303 return true 304 } 305 return false 306 } 307 308 // SetIfNotExistFuncLock sets value with return value of callback function `f`, and then returns true. 309 // It returns false if `key` exists, and `value` would be ignored. 310 // 311 // SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that 312 // it executes function `f` with mutex.Lock of the hash map. 313 func (m *AnyAnyMap) SetIfNotExistFuncLock(key interface{}, f func() interface{}) bool { 314 if !m.Contains(key) { 315 m.doSetWithLockCheck(key, f) 316 return true 317 } 318 return false 319 } 320 321 // Remove deletes value from map by given `key`, and return this deleted value. 322 func (m *AnyAnyMap) Remove(key interface{}) (value interface{}) { 323 m.mu.Lock() 324 if m.data != nil { 325 var ok bool 326 if value, ok = m.data[key]; ok { 327 delete(m.data, key) 328 } 329 } 330 m.mu.Unlock() 331 return 332 } 333 334 // Removes batch deletes values of the map by keys. 335 func (m *AnyAnyMap) Removes(keys []interface{}) { 336 m.mu.Lock() 337 if m.data != nil { 338 for _, key := range keys { 339 delete(m.data, key) 340 } 341 } 342 m.mu.Unlock() 343 } 344 345 // Keys returns all keys of the map as a slice. 346 func (m *AnyAnyMap) Keys() []interface{} { 347 m.mu.RLock() 348 defer m.mu.RUnlock() 349 var ( 350 keys = make([]interface{}, len(m.data)) 351 index = 0 352 ) 353 for key := range m.data { 354 keys[index] = key 355 index++ 356 } 357 return keys 358 } 359 360 // Values returns all values of the map as a slice. 361 func (m *AnyAnyMap) Values() []interface{} { 362 m.mu.RLock() 363 defer m.mu.RUnlock() 364 var ( 365 values = make([]interface{}, len(m.data)) 366 index = 0 367 ) 368 for _, value := range m.data { 369 values[index] = value 370 index++ 371 } 372 return values 373 } 374 375 // Contains checks whether a key exists. 376 // It returns true if the `key` exists, or else false. 377 func (m *AnyAnyMap) Contains(key interface{}) bool { 378 var ok bool 379 m.mu.RLock() 380 if m.data != nil { 381 _, ok = m.data[key] 382 } 383 m.mu.RUnlock() 384 return ok 385 } 386 387 // Size returns the size of the map. 388 func (m *AnyAnyMap) Size() int { 389 m.mu.RLock() 390 length := len(m.data) 391 m.mu.RUnlock() 392 return length 393 } 394 395 // IsEmpty checks whether the map is empty. 396 // It returns true if map is empty, or else false. 397 func (m *AnyAnyMap) IsEmpty() bool { 398 return m.Size() == 0 399 } 400 401 // Clear deletes all data of the map, it will remake a new underlying data map. 402 func (m *AnyAnyMap) Clear() { 403 m.mu.Lock() 404 m.data = make(map[interface{}]interface{}) 405 m.mu.Unlock() 406 } 407 408 // Replace the data of the map with given `data`. 409 func (m *AnyAnyMap) Replace(data map[interface{}]interface{}) { 410 m.mu.Lock() 411 m.data = data 412 m.mu.Unlock() 413 } 414 415 // LockFunc locks writing with given callback function `f` within RWMutex.Lock. 416 func (m *AnyAnyMap) LockFunc(f func(m map[interface{}]interface{})) { 417 m.mu.Lock() 418 defer m.mu.Unlock() 419 f(m.data) 420 } 421 422 // RLockFunc locks reading with given callback function `f` within RWMutex.RLock. 423 func (m *AnyAnyMap) RLockFunc(f func(m map[interface{}]interface{})) { 424 m.mu.RLock() 425 defer m.mu.RUnlock() 426 f(m.data) 427 } 428 429 // Flip exchanges key-value of the map to value-key. 430 func (m *AnyAnyMap) Flip() { 431 m.mu.Lock() 432 defer m.mu.Unlock() 433 n := make(map[interface{}]interface{}, len(m.data)) 434 for k, v := range m.data { 435 n[v] = k 436 } 437 m.data = n 438 } 439 440 // Merge merges two hash maps. 441 // The `other` map will be merged into the map `m`. 442 func (m *AnyAnyMap) Merge(other *AnyAnyMap) { 443 m.mu.Lock() 444 defer m.mu.Unlock() 445 if m.data == nil { 446 m.data = other.MapCopy() 447 return 448 } 449 if other != m { 450 other.mu.RLock() 451 defer other.mu.RUnlock() 452 } 453 for k, v := range other.data { 454 m.data[k] = v 455 } 456 } 457 458 // String returns the map as a string. 459 func (m *AnyAnyMap) String() string { 460 if m == nil { 461 return "" 462 } 463 b, _ := m.MarshalJSON() 464 return string(b) 465 } 466 467 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 468 func (m AnyAnyMap) MarshalJSON() ([]byte, error) { 469 return json.Marshal(gconv.Map(m.Map())) 470 } 471 472 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 473 func (m *AnyAnyMap) UnmarshalJSON(b []byte) error { 474 m.mu.Lock() 475 defer m.mu.Unlock() 476 if m.data == nil { 477 m.data = make(map[interface{}]interface{}) 478 } 479 var data map[string]interface{} 480 if err := json.UnmarshalUseNumber(b, &data); err != nil { 481 return err 482 } 483 for k, v := range data { 484 m.data[k] = v 485 } 486 return nil 487 } 488 489 // UnmarshalValue is an interface implement which sets any type of value for map. 490 func (m *AnyAnyMap) UnmarshalValue(value interface{}) (err error) { 491 m.mu.Lock() 492 defer m.mu.Unlock() 493 if m.data == nil { 494 m.data = make(map[interface{}]interface{}) 495 } 496 for k, v := range gconv.Map(value) { 497 m.data[k] = v 498 } 499 return 500 } 501 502 // DeepCopy implements interface for deep copy of current type. 503 func (m *AnyAnyMap) DeepCopy() interface{} { 504 if m == nil { 505 return nil 506 } 507 508 m.mu.RLock() 509 defer m.mu.RUnlock() 510 data := make(map[interface{}]interface{}, len(m.data)) 511 for k, v := range m.data { 512 data[k] = deepcopy.Copy(v) 513 } 514 return NewFrom(data, m.mu.IsSafe()) 515 } 516 517 // IsSubOf checks whether the current map is a sub-map of `other`. 518 func (m *AnyAnyMap) IsSubOf(other *AnyAnyMap) bool { 519 if m == other { 520 return true 521 } 522 m.mu.RLock() 523 defer m.mu.RUnlock() 524 other.mu.RLock() 525 defer other.mu.RUnlock() 526 for key, value := range m.data { 527 otherValue, ok := other.data[key] 528 if !ok { 529 return false 530 } 531 if otherValue != value { 532 return false 533 } 534 } 535 return true 536 } 537 538 // Diff compares current map `m` with map `other` and returns their different keys. 539 // The returned `addedKeys` are the keys that are in map `m` but not in map `other`. 540 // The returned `removedKeys` are the keys that are in map `other` but not in map `m`. 541 // The returned `updatedKeys` are the keys that are both in map `m` and `other` but their values and not equal (`!=`). 542 func (m *AnyAnyMap) Diff(other *AnyAnyMap) (addedKeys, removedKeys, updatedKeys []interface{}) { 543 m.mu.RLock() 544 defer m.mu.RUnlock() 545 other.mu.RLock() 546 defer other.mu.RUnlock() 547 548 for key := range m.data { 549 if _, ok := other.data[key]; !ok { 550 removedKeys = append(removedKeys, key) 551 } else if !reflect.DeepEqual(m.data[key], other.data[key]) { 552 updatedKeys = append(updatedKeys, key) 553 } 554 } 555 for key := range other.data { 556 if _, ok := m.data[key]; !ok { 557 addedKeys = append(addedKeys, key) 558 } 559 } 560 return 561 }