stickiness_linkedmap.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. *
  3. * Copyright 2018 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package grpc
  19. import (
  20. "container/list"
  21. )
  22. type linkedMapKVPair struct {
  23. key string
  24. value *stickyStoreEntry
  25. }
  26. // linkedMap is an implementation of a map that supports removing the oldest
  27. // entry.
  28. //
  29. // linkedMap is NOT thread safe.
  30. //
  31. // It's for use of stickiness only!
  32. type linkedMap struct {
  33. m map[string]*list.Element
  34. l *list.List // Head of the list is the oldest element.
  35. }
  36. // newLinkedMap returns a new LinkedMap.
  37. func newLinkedMap() *linkedMap {
  38. return &linkedMap{
  39. m: make(map[string]*list.Element),
  40. l: list.New(),
  41. }
  42. }
  43. // put adds entry (key, value) to the map. Existing key will be overridden.
  44. func (m *linkedMap) put(key string, value *stickyStoreEntry) {
  45. if oldE, ok := m.m[key]; ok {
  46. // Remove existing entry.
  47. m.l.Remove(oldE)
  48. }
  49. e := m.l.PushBack(&linkedMapKVPair{key: key, value: value})
  50. m.m[key] = e
  51. }
  52. // get returns the value of the given key.
  53. func (m *linkedMap) get(key string) (*stickyStoreEntry, bool) {
  54. e, ok := m.m[key]
  55. if !ok {
  56. return nil, false
  57. }
  58. m.l.MoveToBack(e)
  59. return e.Value.(*linkedMapKVPair).value, true
  60. }
  61. // remove removes key from the map, and returns the value. The map is not
  62. // modified if key is not in the map.
  63. func (m *linkedMap) remove(key string) (*stickyStoreEntry, bool) {
  64. e, ok := m.m[key]
  65. if !ok {
  66. return nil, false
  67. }
  68. delete(m.m, key)
  69. m.l.Remove(e)
  70. return e.Value.(*linkedMapKVPair).value, true
  71. }
  72. // len returns the len of the map.
  73. func (m *linkedMap) len() int {
  74. return len(m.m)
  75. }
  76. // clear removes all elements from the map.
  77. func (m *linkedMap) clear() {
  78. m.m = make(map[string]*list.Element)
  79. m.l = list.New()
  80. }
  81. // removeOldest removes the oldest key from the map.
  82. func (m *linkedMap) removeOldest() {
  83. e := m.l.Front()
  84. m.l.Remove(e)
  85. delete(m.m, e.Value.(*linkedMapKVPair).key)
  86. }