file_test.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. package hercules
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. )
  6. func updateStatus(
  7. status interface{}, _ int, previous_time int, delta int) {
  8. status.(map[int]int64)[previous_time] += int64(delta)
  9. }
  10. func fixture() (*File, map[int]int64) {
  11. status := map[int]int64{}
  12. file := NewFile(0, 100, NewStatus(status, updateStatus))
  13. return file, status
  14. }
  15. func TestInitialize(t *testing.T) {
  16. file, status := fixture()
  17. dump := file.Dump()
  18. // Output:
  19. // 0 0
  20. // 100 -1
  21. assert.Equal(t, "0 0\n100 -1\n", dump)
  22. assert.Equal(t, int64(100), status[0])
  23. }
  24. func testPanic(t *testing.T, method func(*File), msg string) {
  25. defer func() {
  26. r := recover()
  27. assert.NotNil(t, r, "not panic()-ed")
  28. assert.IsType(t, "", r)
  29. assert.Contains(t, r.(string), msg)
  30. }()
  31. file, _ := fixture()
  32. method(file)
  33. }
  34. func TestBullshit(t *testing.T) {
  35. testPanic(t, func(file *File) { file.Update(1, -10, 10, 0) }, "insert")
  36. testPanic(t, func(file *File) { file.Update(1, 110, 10, 0) }, "insert")
  37. testPanic(t, func(file *File) { file.Update(1, -10, 0, 10) }, "delete")
  38. testPanic(t, func(file *File) { file.Update(1, 100, 0, 10) }, "delete")
  39. testPanic(t, func(file *File) { file.Update(1, 0, -10, 0) }, "length")
  40. testPanic(t, func(file *File) { file.Update(1, 0, 0, -10) }, "length")
  41. testPanic(t, func(file *File) { file.Update(1, 0, -10, -10) }, "length")
  42. testPanic(t, func(file *File) { file.Update(-1, 0, 10, 10) }, "time")
  43. file, status := fixture()
  44. file.Update(1, 10, 0, 0)
  45. assert.Equal(t, int64(100), status[0])
  46. assert.Equal(t, int64(0), status[1])
  47. }
  48. func TestLen(t *testing.T) {
  49. file, _ := fixture()
  50. assert.Equal(t, 100, file.Len())
  51. }
  52. func TestInsert(t *testing.T) {
  53. file, status := fixture()
  54. file.Update(1, 10, 10, 0)
  55. dump := file.Dump()
  56. // Output:
  57. // 0 0
  58. // 10 1
  59. // 20 0
  60. // 110 -1
  61. assert.Equal(t, "0 0\n10 1\n20 0\n110 -1\n", dump)
  62. assert.Equal(t, int64(100), status[0])
  63. assert.Equal(t, int64(10), status[1])
  64. }
  65. func TestZeroInitialize(t *testing.T) {
  66. status := map[int]int64{}
  67. file := NewFile(0, 0, NewStatus(status, updateStatus))
  68. assert.NotContains(t, status, 0)
  69. dump := file.Dump()
  70. // Output:
  71. // 0 -1
  72. assert.Equal(t, "0 -1\n", dump)
  73. file.Update(1, 0, 10, 0)
  74. dump = file.Dump()
  75. // Output:
  76. // 0 1
  77. // 10 -1
  78. assert.Equal(t, "0 1\n10 -1\n", dump)
  79. assert.Equal(t, int64(10), status[1])
  80. }
  81. func TestDelete(t *testing.T) {
  82. file, status := fixture()
  83. file.Update(1, 10, 0, 10)
  84. dump := file.Dump()
  85. // Output:
  86. // 0 0
  87. // 90 -1
  88. assert.Equal(t, "0 0\n90 -1\n", dump)
  89. assert.Equal(t, int64(90), status[0])
  90. assert.Equal(t, int64(0), status[1])
  91. }
  92. func TestFused(t *testing.T) {
  93. file, status := fixture()
  94. file.Update(1, 10, 6, 7)
  95. dump := file.Dump()
  96. // Output:
  97. // 0 0
  98. // 10 1
  99. // 16 0
  100. // 99 -1
  101. assert.Equal(t, "0 0\n10 1\n16 0\n99 -1\n", dump)
  102. assert.Equal(t, int64(93), status[0])
  103. assert.Equal(t, int64(6), status[1])
  104. }
  105. func TestInsertSameTime(t *testing.T) {
  106. file, status := fixture()
  107. file.Update(0, 5, 10, 0)
  108. dump := file.Dump()
  109. // Output:
  110. // 0 0
  111. // 110 -1
  112. assert.Equal(t, "0 0\n110 -1\n", dump)
  113. assert.Equal(t, int64(110), status[0])
  114. }
  115. func TestInsertSameStart(t *testing.T) {
  116. file, status := fixture()
  117. file.Update(1, 10, 10, 0)
  118. file.Update(2, 10, 10, 0)
  119. dump := file.Dump()
  120. // Output:
  121. // 0 0
  122. // 10 2
  123. // 20 1
  124. // 30 0
  125. // 120 -1
  126. assert.Equal(t, "0 0\n10 2\n20 1\n30 0\n120 -1\n", dump)
  127. assert.Equal(t, int64(100), status[0])
  128. assert.Equal(t, int64(10), status[1])
  129. assert.Equal(t, int64(10), status[2])
  130. }
  131. func TestInsertEnd(t *testing.T) {
  132. file, status := fixture()
  133. file.Update(1, 100, 10, 0)
  134. dump := file.Dump()
  135. // Output:
  136. // 0 0
  137. // 100 1
  138. // 110 -1
  139. assert.Equal(t, "0 0\n100 1\n110 -1\n", dump)
  140. assert.Equal(t, int64(100), status[0])
  141. assert.Equal(t, int64(10), status[1])
  142. }
  143. func TestDeleteSameStart0(t *testing.T) {
  144. file, status := fixture()
  145. file.Update(1, 0, 0, 10)
  146. dump := file.Dump()
  147. // Output:
  148. // 0 0
  149. // 90 -1
  150. assert.Equal(t, "0 0\n90 -1\n", dump)
  151. assert.Equal(t, int64(90), status[0])
  152. assert.Equal(t, int64(0), status[1])
  153. }
  154. func TestDeleteSameStartMiddle(t *testing.T) {
  155. file, status := fixture()
  156. file.Update(1, 10, 10, 0)
  157. file.Update(2, 10, 0, 5)
  158. dump := file.Dump()
  159. // Output:
  160. // 0 0
  161. // 10 1
  162. // 15 0
  163. // 105 -1
  164. assert.Equal(t, "0 0\n10 1\n15 0\n105 -1\n", dump)
  165. assert.Equal(t, int64(100), status[0])
  166. assert.Equal(t, int64(5), status[1])
  167. }
  168. func TestDeleteIntersection(t *testing.T) {
  169. file, status := fixture()
  170. file.Update(1, 10, 10, 0)
  171. file.Update(2, 15, 0, 10)
  172. dump := file.Dump()
  173. // Output:
  174. // 0 0
  175. // 10 1
  176. // 15 0
  177. // 100 -1
  178. assert.Equal(t, "0 0\n10 1\n15 0\n100 -1\n", dump)
  179. assert.Equal(t, int64(95), status[0])
  180. assert.Equal(t, int64(5), status[1])
  181. }
  182. func TestDeleteAll(t *testing.T) {
  183. file, status := fixture()
  184. file.Update(1, 0, 0, 100)
  185. // Output:
  186. // 0 -1
  187. dump := file.Dump()
  188. assert.Equal(t, "0 -1\n", dump)
  189. assert.Equal(t, int64(0), status[0])
  190. assert.Equal(t, int64(0), status[1])
  191. }
  192. func TestFusedIntersection(t *testing.T) {
  193. file, status := fixture()
  194. file.Update(1, 10, 10, 0)
  195. file.Update(2, 15, 3, 10)
  196. dump := file.Dump()
  197. // Output:
  198. // 0 0
  199. // 10 1
  200. // 15 2
  201. // 18 0
  202. // 103 -1
  203. assert.Equal(t, "0 0\n10 1\n15 2\n18 0\n103 -1\n", dump)
  204. assert.Equal(t, int64(95), status[0])
  205. assert.Equal(t, int64(5), status[1])
  206. assert.Equal(t, int64(3), status[2])
  207. }
  208. func TestTorture(t *testing.T) {
  209. file, status := fixture()
  210. // 0 0 | 100 -1 [0]: 100
  211. file.Update(1, 20, 30, 0)
  212. // 0 0 | 20 1 | 50 0 | 130 -1 [0]: 100, [1]: 30
  213. file.Update(2, 20, 0, 5)
  214. // 0 0 | 20 1 | 45 0 | 125 -1 [0]: 100, [1]: 25
  215. file.Update(3, 20, 0, 5)
  216. // 0 0 | 20 1 | 40 0 | 120 -1 [0]: 100, [1]: 20
  217. file.Update(4, 20, 10, 0)
  218. // 0 0 | 20 4 | 30 1 | 50 0 | 130 -1 [0]: 100, [1]: 20, [4]: 10
  219. file.Update(5, 45, 0, 10)
  220. // 0 0 | 20 4 | 30 1 | 45 0 | 120 -1 [0]: 95, [1]: 15, [4]: 10
  221. file.Update(6, 45, 5, 0)
  222. // 0 0 | 20 4 | 30 1 | 45 6 | 50 0 | 125 -1 [0]: 95, [1]: 15, [4]: 10, [6]: 5
  223. file.Update(7, 10, 0, 50)
  224. // 0 0 | 75 -1 [0]: 75
  225. file.Update(8, 0, 10, 10)
  226. // 0 8 | 10 0 | 75 -1 [0]: 65, [8]: 10
  227. dump := file.Dump()
  228. assert.Equal(t, "0 8\n10 0\n75 -1\n", dump)
  229. assert.Equal(t, int64(65), status[0])
  230. assert.Equal(t, int64(0), status[1])
  231. assert.Equal(t, int64(0), status[2])
  232. assert.Equal(t, int64(0), status[3])
  233. assert.Equal(t, int64(0), status[4])
  234. assert.Equal(t, int64(0), status[5])
  235. assert.Equal(t, int64(0), status[6])
  236. assert.Equal(t, int64(0), status[7])
  237. assert.Equal(t, int64(10), status[8])
  238. }
  239. func TestInsertDeleteSameTime(t *testing.T) {
  240. file, status := fixture()
  241. file.Update(0, 10, 10, 20)
  242. dump := file.Dump()
  243. assert.Equal(t, "0 0\n90 -1\n", dump)
  244. assert.Equal(t, int64(90), status[0])
  245. file.Update(0, 10, 20, 10)
  246. dump = file.Dump()
  247. assert.Equal(t, "0 0\n100 -1\n", dump)
  248. assert.Equal(t, int64(100), status[0])
  249. }
  250. func TestBug1(t *testing.T) {
  251. file, status := fixture()
  252. file.Update(316, 1, 86, 0)
  253. file.Update(316, 87, 0, 99)
  254. file.Update(251, 0, 1, 0)
  255. file.Update(251, 1, 0, 1)
  256. dump := file.Dump()
  257. assert.Equal(t, "0 251\n1 316\n87 -1\n", dump)
  258. assert.Equal(t, int64(1), status[251])
  259. assert.Equal(t, int64(86), status[316])
  260. file.Update(316, 0, 0, 1)
  261. file.Update(316, 0, 1, 0)
  262. dump = file.Dump()
  263. assert.Equal(t, "0 316\n87 -1\n", dump)
  264. assert.Equal(t, int64(0), status[251])
  265. assert.Equal(t, int64(87), status[316])
  266. }
  267. func TestBug2(t *testing.T) {
  268. file, status := fixture()
  269. file.Update(316, 1, 86, 0)
  270. file.Update(316, 87, 0, 99)
  271. file.Update(251, 0, 1, 0)
  272. file.Update(251, 1, 0, 1)
  273. dump := file.Dump()
  274. assert.Equal(t, "0 251\n1 316\n87 -1\n", dump)
  275. file.Update(316, 0, 1, 1)
  276. dump = file.Dump()
  277. assert.Equal(t, "0 316\n87 -1\n", dump)
  278. assert.Equal(t, int64(0), status[251])
  279. assert.Equal(t, int64(87), status[316])
  280. }
  281. func TestJoin(t *testing.T) {
  282. file, status := fixture()
  283. file.Update(1, 10, 10, 0)
  284. file.Update(1, 30, 10, 0)
  285. file.Update(1, 20, 10, 10)
  286. dump := file.Dump()
  287. assert.Equal(t, "0 0\n10 1\n40 0\n120 -1\n", dump)
  288. assert.Equal(t, int64(90), status[0])
  289. assert.Equal(t, int64(30), status[1])
  290. }
  291. func TestBug3(t *testing.T) {
  292. file, status := fixture()
  293. file.Update(0, 1, 0, 99)
  294. file.Update(0, 0, 1, 1)
  295. dump := file.Dump()
  296. assert.Equal(t, "0 0\n1 -1\n", dump)
  297. assert.Equal(t, int64(1), status[0])
  298. }
  299. func TestBug4(t *testing.T) {
  300. status := map[int]int64{}
  301. file := NewFile(0, 10, NewStatus(status, updateStatus))
  302. file.Update(125, 0, 20, 9)
  303. file.Update(125, 0, 20, 20)
  304. file.Update(166, 12, 1, 1)
  305. file.Update(214, 2, 1, 1)
  306. file.Update(214, 4, 9, 0)
  307. file.Update(214, 27, 1, 1)
  308. file.Update(215, 3, 1, 1)
  309. file.Update(215, 13, 1, 1)
  310. file.Update(215, 17, 1, 1)
  311. file.Update(215, 19, 5, 0)
  312. file.Update(215, 25, 0, 1)
  313. file.Update(215, 31, 6, 1)
  314. file.Update(215, 27, 15, 0)
  315. file.Update(215, 2, 25, 4)
  316. file.Update(215, 28, 1, 1)
  317. file.Update(215, 30, 7, 2)
  318. file.Update(215, 38, 1, 0)
  319. file.Update(215, 40, 4, 2)
  320. file.Update(215, 46, 1, 0)
  321. file.Update(215, 49, 1, 0)
  322. file.Update(215, 52, 2, 6)
  323. dump := file.Dump()
  324. assert.Equal(t, "0 125\n2 215\n48 125\n50 215\n69 125\n73 215\n79 125\n80 0\n81 -1\n", dump)
  325. }
  326. func TestBug5(t *testing.T) {
  327. status := map[int]int64{}
  328. keys := []int{0, 2, 4, 7, 10}
  329. vals := []int{24, 28, 24, 28, -1}
  330. file := NewFileFromTree(keys, vals, NewStatus(status, updateStatus))
  331. file.Update(28, 0, 1, 3)
  332. dump := file.Dump()
  333. assert.Equal(t, "0 28\n2 24\n5 28\n8 -1\n", dump)
  334. keys = []int{0, 1, 16, 18}
  335. vals = []int{305, 0, 157, -1}
  336. file = NewFileFromTree(keys, vals, NewStatus(status, updateStatus))
  337. file.Update(310, 0, 0, 2)
  338. dump = file.Dump()
  339. assert.Equal(t, "0 0\n14 157\n16 -1\n", dump)
  340. }