You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
7.0 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package skiplist
  2. import (
  3. "bytes"
  4. )
  5. type NameList struct {
  6. skipList *SkipList
  7. batchSize int
  8. }
  9. func newNameList(store ListStore, batchSize int) *NameList {
  10. return &NameList{
  11. skipList: New(store),
  12. batchSize: batchSize,
  13. }
  14. }
  15. /*
  16. Be reluctant to create new nodes. Try to fit into either previous node or next node.
  17. Prefer to add to previous node.
  18. There are multiple cases after finding the name for greater or equal node
  19. 1. found and node.Key == name
  20. The node contains a batch with leading key the same as the name
  21. nothing to do
  22. 2. no such node found or node.Key > name
  23. if no such node found
  24. prevNode = list.LargestNode
  25. // case 2.1
  26. if previousNode contains name
  27. nothing to do
  28. // prefer to add to previous node
  29. if prevNode != nil {
  30. // case 2.2
  31. if prevNode has capacity
  32. prevNode.add name, and save
  33. return
  34. // case 2.3
  35. split prevNode by name
  36. }
  37. // case 2.4
  38. // merge into next node. Avoid too many nodes if adding data in reverse order.
  39. if nextNode is not nil and nextNode has capacity
  40. delete nextNode.Key
  41. nextNode.Key = name
  42. nextNode.batch.add name
  43. insert nodeNode.Key
  44. return
  45. // case 2.5
  46. if prevNode is nil
  47. insert new node with key = name, value = batch{name}
  48. return
  49. */
  50. func (nl *NameList) WriteName(name string) error {
  51. lookupKey := []byte(name)
  52. prevNode, nextNode, found, err := nl.skipList.FindGreaterOrEqual(lookupKey)
  53. if err != nil {
  54. return err
  55. }
  56. // case 1: the name already exists as one leading key in the batch
  57. if found && bytes.Compare(nextNode.Key, lookupKey) == 0 {
  58. return nil
  59. }
  60. if !found {
  61. prevNode, err = nl.skipList.GetLargestNode()
  62. if err != nil {
  63. return err
  64. }
  65. }
  66. if nextNode != nil && prevNode == nil {
  67. prevNode, err = nl.skipList.LoadElement(nextNode.Prev)
  68. if err != nil {
  69. return err
  70. }
  71. }
  72. if prevNode != nil {
  73. prevNameBatch := LoadNameBatch(prevNode.Value)
  74. // case 2.1
  75. if prevNameBatch.ContainsName(name) {
  76. return nil
  77. }
  78. // case 2.2
  79. if len(prevNameBatch.names) < nl.batchSize {
  80. prevNameBatch.WriteName(name)
  81. return nl.skipList.ChangeValue(prevNode, prevNameBatch.ToBytes())
  82. }
  83. // case 2.3
  84. x, y := prevNameBatch.SplitBy(name)
  85. addToX := len(x.names) <= len(y.names)
  86. if len(x.names) != len(prevNameBatch.names) {
  87. if addToX {
  88. x.WriteName(name)
  89. }
  90. if x.key == prevNameBatch.key {
  91. if err := nl.skipList.ChangeValue(prevNode, x.ToBytes()); err != nil {
  92. return err
  93. }
  94. } else {
  95. if _, err := nl.skipList.InsertByKey([]byte(x.key), 0, x.ToBytes()); err != nil {
  96. return err
  97. }
  98. }
  99. }
  100. if len(y.names) != len(prevNameBatch.names) {
  101. if !addToX {
  102. y.WriteName(name)
  103. }
  104. if y.key == prevNameBatch.key {
  105. if err := nl.skipList.ChangeValue(prevNode, y.ToBytes()); err != nil {
  106. return err
  107. }
  108. } else {
  109. if _, err := nl.skipList.InsertByKey([]byte(y.key), 0, y.ToBytes()); err != nil {
  110. return err
  111. }
  112. }
  113. }
  114. return nil
  115. }
  116. // case 2.4
  117. if nextNode != nil {
  118. nextNameBatch := LoadNameBatch(nextNode.Value)
  119. if len(nextNameBatch.names) < nl.batchSize {
  120. if _, err := nl.skipList.DeleteByKey(nextNode.Key); err != nil {
  121. return err
  122. }
  123. nextNameBatch.WriteName(name)
  124. if _, err := nl.skipList.InsertByKey([]byte(nextNameBatch.key), 0, nextNameBatch.ToBytes()); err != nil {
  125. return err
  126. }
  127. return nil
  128. }
  129. }
  130. // case 2.5
  131. // now prevNode is nil
  132. newNameBatch := NewNameBatch()
  133. newNameBatch.WriteName(name)
  134. if _, err := nl.skipList.InsertByKey([]byte(newNameBatch.key), 0, newNameBatch.ToBytes()); err != nil {
  135. return err
  136. }
  137. return nil
  138. }
  139. /*
  140. // case 1: exists in nextNode
  141. if nextNode != nil && nextNode.Key == name {
  142. remove from nextNode, update nextNode
  143. // TODO: merge with prevNode if possible?
  144. return
  145. }
  146. if nextNode is nil
  147. prevNode = list.Largestnode
  148. if prevNode == nil and nextNode.Prev != nil
  149. prevNode = load(nextNode.Prev)
  150. // case 2: does not exist
  151. // case 2.1
  152. if prevNode == nil {
  153. return
  154. }
  155. // case 2.2
  156. if prevNameBatch does not contain name {
  157. return
  158. }
  159. // case 3
  160. delete from prevNameBatch
  161. if prevNameBatch + nextNode < capacityList
  162. // case 3.1
  163. merge
  164. else
  165. // case 3.2
  166. update prevNode
  167. */
  168. func (nl *NameList) DeleteName(name string) error {
  169. lookupKey := []byte(name)
  170. prevNode, nextNode, found, err := nl.skipList.FindGreaterOrEqual(lookupKey)
  171. if err != nil {
  172. return err
  173. }
  174. // case 1
  175. var nextNameBatch *NameBatch
  176. if nextNode != nil {
  177. nextNameBatch = LoadNameBatch(nextNode.Value)
  178. }
  179. if found && bytes.Compare(nextNode.Key, lookupKey) == 0 {
  180. if _, err := nl.skipList.DeleteByKey(nextNode.Key); err != nil {
  181. return err
  182. }
  183. nextNameBatch.DeleteName(name)
  184. if len(nextNameBatch.names) > 0 {
  185. if _, err := nl.skipList.InsertByKey([]byte(nextNameBatch.key), 0, nextNameBatch.ToBytes()); err != nil {
  186. return err
  187. }
  188. }
  189. return nil
  190. }
  191. if !found {
  192. prevNode, err = nl.skipList.GetLargestNode()
  193. if err != nil {
  194. return err
  195. }
  196. }
  197. if nextNode != nil && prevNode == nil {
  198. prevNode, err = nl.skipList.LoadElement(nextNode.Prev)
  199. if err != nil {
  200. return err
  201. }
  202. }
  203. // case 2
  204. if prevNode == nil {
  205. // case 2.1
  206. return nil
  207. }
  208. prevNameBatch := LoadNameBatch(prevNode.Value)
  209. if !prevNameBatch.ContainsName(name) {
  210. // case 2.2
  211. return nil
  212. }
  213. // case 3
  214. prevNameBatch.DeleteName(name)
  215. if len(prevNameBatch.names) == 0 {
  216. if _, err := nl.skipList.DeleteByKey(prevNode.Key); err != nil {
  217. return err
  218. }
  219. return nil
  220. }
  221. if nextNameBatch != nil && len(nextNameBatch.names)+len(prevNameBatch.names) < nl.batchSize {
  222. // case 3.1 merge nextNode and prevNode
  223. if _, err := nl.skipList.DeleteByKey(nextNode.Key); err != nil {
  224. return err
  225. }
  226. for nextName := range nextNameBatch.names {
  227. prevNameBatch.WriteName(nextName)
  228. }
  229. return nl.skipList.ChangeValue(prevNode, prevNameBatch.ToBytes())
  230. } else {
  231. // case 3.2 update prevNode
  232. return nl.skipList.ChangeValue(prevNode, prevNameBatch.ToBytes())
  233. }
  234. return nil
  235. }
  236. func (nl *NameList) ListNames(startFrom string, visitNamesFn func(name string) bool) error {
  237. lookupKey := []byte(startFrom)
  238. prevNode, nextNode, found, err := nl.skipList.FindGreaterOrEqual(lookupKey)
  239. if err != nil {
  240. return err
  241. }
  242. if found && bytes.Compare(nextNode.Key, lookupKey) == 0 {
  243. prevNode = nil
  244. }
  245. if !found {
  246. prevNode, err = nl.skipList.GetLargestNode()
  247. if err != nil {
  248. return err
  249. }
  250. }
  251. if prevNode != nil {
  252. prevNameBatch := LoadNameBatch(prevNode.Value)
  253. if !prevNameBatch.ListNames(startFrom, visitNamesFn) {
  254. return nil
  255. }
  256. }
  257. for nextNode != nil {
  258. nextNameBatch := LoadNameBatch(nextNode.Value)
  259. if !nextNameBatch.ListNames(startFrom, visitNamesFn) {
  260. return nil
  261. }
  262. nextNode, err = nl.skipList.LoadElement(nextNode.Next[0])
  263. if err != nil {
  264. return err
  265. }
  266. }
  267. return nil
  268. }
  269. func (nl *NameList) RemoteAllListElement() error {
  270. t := nl.skipList
  271. nodeRef := t.StartLevels[0]
  272. for nodeRef != nil {
  273. node, err := t.LoadElement(nodeRef)
  274. if err != nil {
  275. return err
  276. }
  277. if node == nil {
  278. return nil
  279. }
  280. if err := t.DeleteElement(node); err != nil {
  281. return err
  282. }
  283. nodeRef = node.Next[0]
  284. }
  285. return nil
  286. }