rbtree_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. package rbtree
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "math/rand"
  6. "os"
  7. "sort"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. // Create a tree storing a set of integers
  12. func testNewIntSet() *RBTree {
  13. return NewRBTree(NewAllocator())
  14. }
  15. func testAssert(t *testing.T, b bool, message string) {
  16. assert.True(t, b, message)
  17. }
  18. func boolInsert(tree *RBTree, item int) bool {
  19. status, _ := tree.Insert(Item{uint32(item), uint32(item)})
  20. return status
  21. }
  22. func TestEmpty(t *testing.T) {
  23. tree := testNewIntSet()
  24. testAssert(t, tree.Len() == 0, "len!=0")
  25. testAssert(t, tree.Max().NegativeLimit(), "neglimit")
  26. testAssert(t, tree.Min().Limit(), "limit")
  27. testAssert(t, tree.FindGE(10).Limit(), "Not empty")
  28. testAssert(t, tree.FindLE(10).NegativeLimit(), "Not empty")
  29. testAssert(t, tree.Get(10) == nil, "Not empty")
  30. testAssert(t, tree.Limit().Equal(tree.Min()), "iter")
  31. }
  32. func TestFindGE(t *testing.T) {
  33. tree := testNewIntSet()
  34. testAssert(t, boolInsert(tree, 10), "Insert1")
  35. testAssert(t, !boolInsert(tree, 10), "Insert2")
  36. testAssert(t, tree.Len() == 1, "len==1")
  37. testAssert(t, tree.FindGE(10).Item().Key == 10, "FindGE 10")
  38. testAssert(t, tree.FindGE(11).Limit(), "FindGE 11")
  39. assert.Equal(t, tree.FindGE(9).Item().Key, uint32(10), "FindGE 10")
  40. }
  41. func TestFindLE(t *testing.T) {
  42. tree := testNewIntSet()
  43. testAssert(t, boolInsert(tree, 10), "insert1")
  44. testAssert(t, tree.FindLE(10).Item().Key == 10, "FindLE 10")
  45. testAssert(t, tree.FindLE(11).Item().Key == 10, "FindLE 11")
  46. testAssert(t, tree.FindLE(9).NegativeLimit(), "FindLE 9")
  47. }
  48. func TestGet(t *testing.T) {
  49. tree := testNewIntSet()
  50. testAssert(t, boolInsert(tree, 10), "insert1")
  51. assert.Equal(t, *tree.Get(10), uint32(10), "Get 10")
  52. testAssert(t, tree.Get(9) == nil, "Get 9")
  53. testAssert(t, tree.Get(11) == nil, "Get 11")
  54. }
  55. func TestDelete(t *testing.T) {
  56. tree := testNewIntSet()
  57. testAssert(t, !tree.DeleteWithKey(10), "del")
  58. testAssert(t, tree.Len() == 0, "dellen")
  59. testAssert(t, boolInsert(tree, 10), "ins")
  60. testAssert(t, tree.DeleteWithKey(10), "del")
  61. testAssert(t, tree.Len() == 0, "dellen")
  62. // delete was deleting after the request if request not found
  63. // ensure this does not regress:
  64. testAssert(t, boolInsert(tree, 10), "ins")
  65. testAssert(t, !tree.DeleteWithKey(9), "del")
  66. testAssert(t, tree.Len() == 1, "dellen")
  67. }
  68. func iterToString(i Iterator) string {
  69. s := ""
  70. for ; !i.Limit(); i = i.Next() {
  71. if s != "" {
  72. s = s + ","
  73. }
  74. s = s + fmt.Sprintf("%d", i.Item().Key)
  75. }
  76. return s
  77. }
  78. func reverseIterToString(i Iterator) string {
  79. s := ""
  80. for ; !i.NegativeLimit(); i = i.Prev() {
  81. if s != "" {
  82. s = s + ","
  83. }
  84. s = s + fmt.Sprintf("%d", i.Item().Key)
  85. }
  86. return s
  87. }
  88. func TestIterator(t *testing.T) {
  89. tree := testNewIntSet()
  90. for i := 0; i < 10; i = i + 2 {
  91. boolInsert(tree, i)
  92. }
  93. assert.Equal(t, iterToString(tree.FindGE(3)), "4,6,8")
  94. assert.Equal(t, iterToString(tree.FindGE(4)), "4,6,8")
  95. assert.Equal(t, iterToString(tree.FindGE(8)), "8")
  96. assert.Equal(t, iterToString(tree.FindGE(9)), "")
  97. assert.Equal(t, reverseIterToString(tree.FindLE(3)), "2,0")
  98. assert.Equal(t, reverseIterToString(tree.FindLE(2)), "2,0")
  99. assert.Equal(t, reverseIterToString(tree.FindLE(0)), "0")
  100. }
  101. //
  102. // Randomized tests
  103. //
  104. // oracle stores provides an interface similar to rbtree, but stores
  105. // data in an sorted array
  106. type oracle struct {
  107. data []int
  108. }
  109. func newOracle() *oracle {
  110. return &oracle{data: make([]int, 0)}
  111. }
  112. func (o *oracle) Len() int {
  113. return len(o.data)
  114. }
  115. // interface needed for sorting
  116. func (o *oracle) Less(i, j int) bool {
  117. return o.data[i] < o.data[j]
  118. }
  119. func (o *oracle) Swap(i, j int) {
  120. e := o.data[j]
  121. o.data[j] = o.data[i]
  122. o.data[i] = e
  123. }
  124. func (o *oracle) Insert(key int) bool {
  125. for _, e := range o.data {
  126. if e == key {
  127. return false
  128. }
  129. }
  130. n := len(o.data) + 1
  131. newData := make([]int, n)
  132. copy(newData, o.data)
  133. newData[n-1] = key
  134. o.data = newData
  135. sort.Sort(o)
  136. return true
  137. }
  138. func (o *oracle) RandomExistingKey(rand *rand.Rand) int {
  139. index := rand.Int31n(int32(len(o.data)))
  140. return o.data[index]
  141. }
  142. func (o *oracle) FindGE(t *testing.T, key int) oracleIterator {
  143. prev := int(-1)
  144. for i, e := range o.data {
  145. if e <= prev {
  146. t.Fatal("Nonsorted oracle ", e, prev)
  147. }
  148. if e >= key {
  149. return oracleIterator{o: o, index: i}
  150. }
  151. }
  152. return oracleIterator{o: o, index: len(o.data)}
  153. }
  154. func (o *oracle) FindLE(t *testing.T, key int) oracleIterator {
  155. iter := o.FindGE(t, key)
  156. if !iter.Limit() && o.data[iter.index] == key {
  157. return iter
  158. }
  159. return oracleIterator{o, iter.index - 1}
  160. }
  161. func (o *oracle) Delete(key int) bool {
  162. for i, e := range o.data {
  163. if e == key {
  164. newData := make([]int, len(o.data)-1)
  165. copy(newData, o.data[0:i])
  166. copy(newData[i:], o.data[i+1:])
  167. o.data = newData
  168. return true
  169. }
  170. }
  171. return false
  172. }
  173. //
  174. // Test iterator
  175. //
  176. type oracleIterator struct {
  177. o *oracle
  178. index int
  179. }
  180. func (oiter oracleIterator) Limit() bool {
  181. return oiter.index >= len(oiter.o.data)
  182. }
  183. func (oiter oracleIterator) Min() bool {
  184. return oiter.index == 0
  185. }
  186. func (oiter oracleIterator) NegativeLimit() bool {
  187. return oiter.index < 0
  188. }
  189. func (oiter oracleIterator) Max() bool {
  190. return oiter.index == len(oiter.o.data)-1
  191. }
  192. func (oiter oracleIterator) Item() int {
  193. return oiter.o.data[oiter.index]
  194. }
  195. func (oiter oracleIterator) Next() oracleIterator {
  196. return oracleIterator{oiter.o, oiter.index + 1}
  197. }
  198. func (oiter oracleIterator) Prev() oracleIterator {
  199. return oracleIterator{oiter.o, oiter.index - 1}
  200. }
  201. func compareContents(t *testing.T, oiter oracleIterator, titer Iterator) {
  202. oi := oiter
  203. ti := titer
  204. // Test forward iteration
  205. testAssert(t, oi.NegativeLimit() == ti.NegativeLimit(), "rend")
  206. if oi.NegativeLimit() {
  207. oi = oi.Next()
  208. ti = ti.Next()
  209. }
  210. for !oi.Limit() && !ti.Limit() {
  211. // log.Print("Item: ", oi.Item(), ti.Item())
  212. if ti.Item().Key != uint32(oi.Item()) {
  213. t.Fatal("Wrong item", ti.Item(), oi.Item())
  214. }
  215. oi = oi.Next()
  216. ti = ti.Next()
  217. }
  218. if !ti.Limit() {
  219. t.Fatal("!ti.done", ti.Item())
  220. }
  221. if !oi.Limit() {
  222. t.Fatal("!oi.done", oi.Item())
  223. }
  224. // Test reverse iteration
  225. oi = oiter
  226. ti = titer
  227. testAssert(t, oi.Limit() == ti.Limit(), "end")
  228. if oi.Limit() {
  229. oi = oi.Prev()
  230. ti = ti.Prev()
  231. }
  232. for !oi.NegativeLimit() && !ti.NegativeLimit() {
  233. if ti.Item().Key != uint32(oi.Item()) {
  234. t.Fatal("Wrong item", ti.Item(), oi.Item())
  235. }
  236. oi = oi.Prev()
  237. ti = ti.Prev()
  238. }
  239. if !ti.NegativeLimit() {
  240. t.Fatal("!ti.done", ti.Item())
  241. }
  242. if !oi.NegativeLimit() {
  243. t.Fatal("!oi.done", oi.Item())
  244. }
  245. }
  246. func compareContentsFull(t *testing.T, o *oracle, tree *RBTree) {
  247. compareContents(t, o.FindGE(t, -1), tree.FindGE(0))
  248. }
  249. func TestRandomized(t *testing.T) {
  250. const numKeys = 1000
  251. o := newOracle()
  252. tree := testNewIntSet()
  253. r := rand.New(rand.NewSource(0))
  254. for i := 0; i < 10000; i++ {
  255. op := r.Int31n(100)
  256. if op < 50 {
  257. key := r.Int31n(numKeys)
  258. o.Insert(int(key))
  259. boolInsert(tree, int(key))
  260. compareContentsFull(t, o, tree)
  261. } else if op < 90 && o.Len() > 0 {
  262. key := o.RandomExistingKey(r)
  263. o.Delete(key)
  264. if !tree.DeleteWithKey(uint32(key)) {
  265. t.Fatal("DeleteExisting", key)
  266. }
  267. compareContentsFull(t, o, tree)
  268. } else if op < 95 {
  269. key := int(r.Int31n(numKeys))
  270. compareContents(t, o.FindGE(t, key), tree.FindGE(uint32(key)))
  271. } else {
  272. key := int(r.Int31n(numKeys))
  273. compareContents(t, o.FindLE(t, key), tree.FindLE(uint32(key)))
  274. }
  275. }
  276. }
  277. func TestAllocatorFreeZero(t *testing.T) {
  278. alloc := NewAllocator()
  279. alloc.malloc()
  280. assert.Panics(t, func() { alloc.free(0) })
  281. }
  282. func TestCloneShallow(t *testing.T) {
  283. alloc1 := NewAllocator()
  284. alloc1.malloc()
  285. tree := NewRBTree(alloc1)
  286. tree.Insert(Item{7, 7})
  287. tree.Insert(Item{8, 8})
  288. tree.DeleteWithKey(8)
  289. assert.Equal(t, alloc1.storage, []node{{}, {}, {color: black, item: Item{7, 7}}, {}})
  290. assert.Equal(t, tree.minNode, uint32(2))
  291. assert.Equal(t, tree.maxNode, uint32(2))
  292. alloc2 := alloc1.Clone()
  293. clone := tree.CloneShallow(alloc2)
  294. assert.Equal(t, alloc2.storage, []node{{}, {}, {color: black, item: Item{7, 7}}, {}})
  295. assert.Equal(t, clone.minNode, uint32(2))
  296. assert.Equal(t, clone.maxNode, uint32(2))
  297. assert.Equal(t, alloc2.Size(), 4)
  298. tree.Insert(Item{10, 10})
  299. alloc3 := alloc1.Clone()
  300. clone = tree.CloneShallow(alloc3)
  301. assert.Equal(t, alloc3.storage, []node{
  302. {}, {},
  303. {right: 3, color: black, item: Item{7, 7}},
  304. {parent: 2, color: red, item: Item{10, 10}}})
  305. assert.Equal(t, clone.minNode, uint32(2))
  306. assert.Equal(t, clone.maxNode, uint32(3))
  307. assert.Equal(t, alloc3.Size(), 4)
  308. assert.Equal(t, alloc2.Size(), 4)
  309. }
  310. func TestCloneDeep(t *testing.T) {
  311. alloc1 := NewAllocator()
  312. alloc1.malloc()
  313. tree := NewRBTree(alloc1)
  314. tree.Insert(Item{7, 7})
  315. assert.Equal(t, alloc1.storage, []node{{}, {}, {color: black, item: Item{7, 7}}})
  316. assert.Equal(t, tree.minNode, uint32(2))
  317. assert.Equal(t, tree.maxNode, uint32(2))
  318. alloc2 := NewAllocator()
  319. clone := tree.CloneDeep(alloc2)
  320. assert.Equal(t, alloc2.storage, []node{{}, {color: black, item: Item{7, 7}}})
  321. assert.Equal(t, clone.minNode, uint32(1))
  322. assert.Equal(t, clone.maxNode, uint32(1))
  323. assert.Equal(t, alloc2.Size(), 2)
  324. tree.Insert(Item{10, 10})
  325. alloc2 = NewAllocator()
  326. clone = tree.CloneDeep(alloc2)
  327. assert.Equal(t, alloc2.storage, []node{
  328. {},
  329. {right: 2, color: black, item: Item{7, 7}},
  330. {parent: 1, color: red, item: Item{10, 10}}})
  331. assert.Equal(t, clone.minNode, uint32(1))
  332. assert.Equal(t, clone.maxNode, uint32(2))
  333. assert.Equal(t, alloc2.Size(), 3)
  334. }
  335. func TestErase(t *testing.T) {
  336. alloc := NewAllocator()
  337. tree := NewRBTree(alloc)
  338. for i := 0; i < 10; i++ {
  339. tree.Insert(Item{uint32(i), uint32(i)})
  340. }
  341. assert.Equal(t, alloc.Used(), 11)
  342. tree.Erase()
  343. assert.Equal(t, alloc.Used(), 1)
  344. assert.Equal(t, alloc.Size(), 11)
  345. }
  346. func TestAllocatorHibernateBoot(t *testing.T) {
  347. alloc := NewAllocator()
  348. for i := 0; i < 10000; i++ {
  349. n := alloc.malloc()
  350. alloc.storage[n].item.Key = uint32(i)
  351. alloc.storage[n].item.Value = uint32(i)
  352. alloc.storage[n].left = uint32(i)
  353. alloc.storage[n].right = uint32(i)
  354. alloc.storage[n].parent = uint32(i)
  355. alloc.storage[n].color = i%2 == 0
  356. }
  357. for i := 0; i < 10000; i++ {
  358. alloc.gaps[uint32(i)] = true // makes no sense, only to test
  359. }
  360. alloc.Hibernate()
  361. assert.PanicsWithValue(t, "cannot hibernate an already hibernated Allocator", alloc.Hibernate)
  362. assert.Nil(t, alloc.storage)
  363. assert.Nil(t, alloc.gaps)
  364. assert.Equal(t, alloc.Size(), 0)
  365. assert.Equal(t, alloc.hibernatedStorageLen, 10001)
  366. assert.Equal(t, alloc.hibernatedGapsLen, 10000)
  367. assert.PanicsWithValue(t, "hibernated allocators cannot be used", func() { alloc.Used() })
  368. assert.PanicsWithValue(t, "hibernated allocators cannot be used", func() { alloc.malloc() })
  369. assert.PanicsWithValue(t, "hibernated allocators cannot be used", func() { alloc.free(0) })
  370. assert.PanicsWithValue(t, "cannot clone a hibernated allocator", func() { alloc.Clone() })
  371. alloc.Boot()
  372. assert.Equal(t, alloc.hibernatedStorageLen, 0)
  373. assert.Equal(t, alloc.hibernatedGapsLen, 0)
  374. for n := 1; n <= 10000; n++ {
  375. assert.Equal(t, alloc.storage[n].item.Key, uint32(n-1))
  376. assert.Equal(t, alloc.storage[n].item.Value, uint32(n-1))
  377. assert.Equal(t, alloc.storage[n].left, uint32(n-1))
  378. assert.Equal(t, alloc.storage[n].right, uint32(n-1))
  379. assert.Equal(t, alloc.storage[n].parent, uint32(n-1))
  380. assert.Equal(t, alloc.storage[n].color, (n-1)%2 == 0)
  381. assert.True(t, alloc.gaps[uint32(n-1)])
  382. }
  383. }
  384. func TestAllocatorHibernateBootEmpty(t *testing.T) {
  385. alloc := NewAllocator()
  386. alloc.Hibernate()
  387. alloc.Boot()
  388. assert.NotNil(t, alloc.gaps)
  389. assert.Equal(t, alloc.Size(), 0)
  390. assert.Equal(t, alloc.Used(), 0)
  391. }
  392. func TestAllocatorHibernateBootThreshold(t *testing.T) {
  393. alloc := NewAllocator()
  394. alloc.malloc()
  395. alloc.HibernationThreshold = 3
  396. assert.Equal(t, 3, alloc.Clone().HibernationThreshold)
  397. alloc.Hibernate()
  398. assert.Equal(t, alloc.hibernatedStorageLen, 0)
  399. alloc.Boot()
  400. alloc.malloc()
  401. alloc.Hibernate()
  402. assert.Equal(t, alloc.hibernatedGapsLen, 0)
  403. assert.Equal(t, alloc.hibernatedStorageLen, 3)
  404. alloc.Boot()
  405. assert.Equal(t, alloc.Size(), 3)
  406. assert.Equal(t, alloc.Used(), 3)
  407. assert.NotNil(t, alloc.gaps)
  408. }
  409. func TestAllocatorSerializeDeserialize(t *testing.T) {
  410. alloc := NewAllocator()
  411. for i := 0; i < 10000; i++ {
  412. n := alloc.malloc()
  413. alloc.storage[n].item.Key = uint32(i)
  414. alloc.storage[n].item.Value = uint32(i)
  415. alloc.storage[n].left = uint32(i)
  416. alloc.storage[n].right = uint32(i)
  417. alloc.storage[n].parent = uint32(i)
  418. alloc.storage[n].color = i%2 == 0
  419. }
  420. for i := 0; i < 10000; i++ {
  421. alloc.gaps[uint32(i)] = true // makes no sense, only to test
  422. }
  423. assert.PanicsWithValue(t, "serialization requires the hibernated state",
  424. func() { alloc.Serialize("...") })
  425. assert.PanicsWithValue(t, "deserialization requires the hibernated state",
  426. func() { alloc.Deserialize("...") })
  427. alloc.Hibernate()
  428. file, err := ioutil.TempFile("", "")
  429. assert.Nil(t, err)
  430. name := file.Name()
  431. defer os.Remove(name)
  432. assert.Nil(t, file.Close())
  433. assert.NotNil(t, alloc.Serialize("/tmp/xxx/yyy"))
  434. assert.Nil(t, alloc.Serialize(name))
  435. assert.Nil(t, alloc.storage)
  436. assert.Nil(t, alloc.gaps)
  437. for _, d := range alloc.hibernatedData {
  438. assert.Nil(t, d)
  439. }
  440. assert.Equal(t, alloc.hibernatedStorageLen, 10001)
  441. assert.Equal(t, alloc.hibernatedGapsLen, 10000)
  442. assert.PanicsWithValue(t, "cannot boot a serialized Allocator", alloc.Boot)
  443. assert.NotNil(t, alloc.Deserialize("/tmp/xxx/yyy"))
  444. assert.Nil(t, alloc.Deserialize(name))
  445. for _, d := range alloc.hibernatedData {
  446. assert.True(t, len(d) > 0)
  447. }
  448. alloc.Boot()
  449. assert.Equal(t, alloc.hibernatedStorageLen, 0)
  450. assert.Equal(t, alloc.hibernatedGapsLen, 0)
  451. for _, d := range alloc.hibernatedData {
  452. assert.Nil(t, d)
  453. }
  454. for n := 1; n <= 10000; n++ {
  455. assert.Equal(t, alloc.storage[n].item.Key, uint32(n-1))
  456. assert.Equal(t, alloc.storage[n].item.Value, uint32(n-1))
  457. assert.Equal(t, alloc.storage[n].left, uint32(n-1))
  458. assert.Equal(t, alloc.storage[n].right, uint32(n-1))
  459. assert.Equal(t, alloc.storage[n].parent, uint32(n-1))
  460. assert.Equal(t, alloc.storage[n].color, (n-1)%2 == 0)
  461. assert.True(t, alloc.gaps[uint32(n-1)])
  462. }
  463. alloc.Hibernate()
  464. assert.Nil(t, os.Truncate(name, 100))
  465. assert.NotNil(t, alloc.Deserialize(name))
  466. assert.Nil(t, os.Truncate(name, 4))
  467. assert.NotNil(t, alloc.Deserialize(name))
  468. assert.Nil(t, os.Truncate(name, 0))
  469. assert.NotNil(t, alloc.Deserialize(name))
  470. }