trtree.nim 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. discard """
  2. output: '''1 [2, 3, 4, 7]
  3. [0, 0]'''
  4. targets: "c"
  5. joinable: false
  6. disabled: 32bit
  7. cmd: "nim c --gc:arc $file"
  8. """
  9. # bug #13110: This test failed with --gc:arc.
  10. # this test wasn't written for 32 bit
  11. # don't join because the code is too messy.
  12. # Nim RTree and R*Tree implementation
  13. # S. Salewski, 06-JAN-2018
  14. # http://www-db.deis.unibo.it/courses/SI-LS/papers/Gut84.pdf
  15. # http://dbs.mathematik.uni-marburg.de/publications/myPapers/1990/BKSS90.pdf
  16. # RT: range type like float, int
  17. # D: Dimension
  18. # M: Max entries in one node
  19. # LT: leaf type
  20. type
  21. Dim* = static[int]
  22. Ext[RT] = tuple[a, b: RT] # extend (range)
  23. Box*[D: Dim; RT] = array[D, Ext[RT]] # Rectangle for 2D
  24. BoxCenter*[D: Dim; RT] = array[D, RT]
  25. L*[D: Dim; RT, LT] = tuple[b: Box[D, RT]; l: LT] # called Index Entry or index record in the Guttman paper
  26. H[M, D: Dim; RT, LT] = ref object of RootRef
  27. parent: H[M, D, RT, LT]
  28. numEntries: int
  29. level: int
  30. N[M, D: Dim; RT, LT] = tuple[b: Box[D, RT]; n: H[M, D, RT, LT]]
  31. LA[M, D: Dim; RT, LT] = array[M, L[D, RT, LT]]
  32. NA[M, D: Dim; RT, LT] = array[M, N[M, D, RT, LT]]
  33. Leaf[M, D: Dim; RT, LT] = ref object of H[M, D, RT, LT]
  34. a: LA[M, D, RT, LT]
  35. Node[M, D: Dim; RT, LT] = ref object of H[M, D, RT, LT]
  36. a: NA[M, D, RT, LT]
  37. RTree*[M, D: Dim; RT, LT] = ref object of RootRef
  38. root: H[M, D, RT, LT]
  39. bigM: int
  40. m: int
  41. RStarTree*[M, D: Dim; RT, LT] = ref object of RTree[M, D, RT, LT]
  42. firstOverflow: array[32, bool]
  43. p: int
  44. proc newLeaf[M, D: Dim; RT, LT](): Leaf[M, D, RT, LT] =
  45. new result
  46. proc newNode[M, D: Dim; RT, LT](): Node[M, D, RT, LT] =
  47. new result
  48. proc newRTree*[M, D: Dim; RT, LT](minFill: range[30 .. 50] = 40): RTree[M, D, RT, LT] =
  49. assert(M > 1 and M < 101)
  50. new result
  51. result.bigM = M
  52. result.m = M * minFill div 100
  53. result.root = newLeaf[M, D, RT, LT]()
  54. proc newRStarTree*[M, D: Dim; RT, LT](minFill: range[30 .. 50] = 40): RStarTree[M, D, RT, LT] =
  55. assert(M > 1 and M < 101)
  56. new result
  57. result.bigM = M
  58. result.m = M * minFill div 100
  59. result.p = M * 30 div 100
  60. result.root = newLeaf[M, D, RT, LT]()
  61. proc center(r: Box): auto =#BoxCenter[r.len, typeof(r[0].a)] =
  62. var res = default(BoxCenter[r.len, typeof(r[0].a)])
  63. for i in 0 .. r.high:
  64. when r[0].a is SomeInteger:
  65. res[i] = (r[i].a + r[i].b) div 2
  66. elif r[0].a is SomeFloat:
  67. res[i] = (r[i].a + r[i].b) / 2
  68. else: assert false
  69. return res
  70. proc distance(c1, c2: BoxCenter): auto =
  71. var res: typeof(c1[0]) = default(typeof(c1[0]))
  72. for i in 0 .. c1.high:
  73. res += (c1[i] - c2[i]) * (c1[i] - c2[i])
  74. return res
  75. proc overlap(r1, r2: Box): auto =
  76. result = typeof(r1[0].a)(1)
  77. for i in 0 .. r1.high:
  78. result *= (min(r1[i].b, r2[i].b) - max(r1[i].a, r2[i].a))
  79. if result <= 0: return 0
  80. proc union(r1, r2: Box): Box =
  81. result = default(Box)
  82. for i in 0 .. r1.high:
  83. result[i].a = min(r1[i].a, r2[i].a)
  84. result[i].b = max(r1[i].b, r2[i].b)
  85. proc intersect(r1, r2: Box): bool =
  86. for i in 0 .. r1.high:
  87. if r1[i].b < r2[i].a or r1[i].a > r2[i].b:
  88. return false
  89. return true
  90. proc area(r: Box): auto = #typeof(r[0].a) =
  91. result = typeof(r[0].a)(1)
  92. for i in 0 .. r.high:
  93. result *= r[i].b - r[i].a
  94. proc margin(r: Box): auto = #typeof(r[0].a) =
  95. result = typeof(r[0].a)(0)
  96. for i in 0 .. r.high:
  97. result += r[i].b - r[i].a
  98. # how much enlargement does r1 need to include r2
  99. proc enlargement(r1, r2: Box): auto =
  100. area(union(r1, r2)) - area(r1)
  101. proc search*[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; b: Box[D, RT]): seq[LT] =
  102. proc s[M, D: Dim; RT, LT](n: H[M, D, RT, LT]; b: Box[D, RT]; res: var seq[LT]) =
  103. if n of Node[M, D, RT, LT]:
  104. let h = Node[M, D, RT, LT](n)
  105. for i in 0 ..< n.numEntries:
  106. if intersect(h.a[i].b, b):
  107. s(h.a[i].n, b, res)
  108. elif n of Leaf[M, D, RT, LT]:
  109. let h = Leaf[M, D, RT, LT](n)
  110. for i in 0 ..< n.numEntries:
  111. if intersect(h.a[i].b, b):
  112. res.add(h.a[i].l)
  113. else: assert false
  114. result = newSeq[LT]()
  115. s(t.root, b, result)
  116. # Insertion
  117. # a R*TREE proc
  118. proc chooseSubtree[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; b: Box[D, RT]; level: int): H[M, D, RT, LT] =
  119. assert level >= 0
  120. var it = t.root
  121. while it.level > level:
  122. let nn = Node[M, D, RT, LT](it)
  123. var i0 = 0 # selected index
  124. var minLoss = typeof(b[0].a).high
  125. if it.level == 1: # childreen are leaves -- determine the minimum overlap costs
  126. for i in 0 ..< it.numEntries:
  127. let nx = union(nn.a[i].b, b)
  128. var loss = 0
  129. for j in 0 ..< it.numEntries:
  130. if i == j: continue
  131. loss += (overlap(nx, nn.a[j].b) - overlap(nn.a[i].b, nn.a[j].b)) # overlap (i, j) == (j, i), so maybe cache that?
  132. var rep = loss < minLoss
  133. if loss == minLoss:
  134. let l2 = enlargement(nn.a[i].b, b) - enlargement(nn.a[i0].b, b)
  135. rep = l2 < 0
  136. if l2 == 0:
  137. let l3 = area(nn.a[i].b) - area(nn.a[i0].b)
  138. rep = l3 < 0
  139. if l3 == 0:
  140. rep = nn.a[i].n.numEntries < nn.a[i0].n.numEntries
  141. if rep:
  142. i0 = i
  143. minLoss = loss
  144. else:
  145. for i in 0 ..< it.numEntries:
  146. let loss = enlargement(nn.a[i].b, b)
  147. var rep = loss < minLoss
  148. if loss == minLoss:
  149. let l3 = area(nn.a[i].b) - area(nn.a[i0].b)
  150. rep = l3 < 0
  151. if l3 == 0:
  152. rep = nn.a[i].n.numEntries < nn.a[i0].n.numEntries
  153. if rep:
  154. i0 = i
  155. minLoss = loss
  156. it = nn.a[i0].n
  157. return it
  158. proc pickSeeds[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; n: Node[M, D, RT, LT] | Leaf[M, D, RT, LT]; bx: Box[D, RT]): (int, int) =
  159. var i0, j0: int = 0
  160. var bi, bj: typeof(bx)
  161. var largestWaste = typeof(bx[0].a).low
  162. for i in -1 .. n.a.high:
  163. for j in 0 .. n.a.high:
  164. if unlikely(i == j): continue
  165. if unlikely(i < 0):
  166. bi = bx
  167. else:
  168. bi = n.a[i].b
  169. bj = n.a[j].b
  170. let b = union(bi, bj)
  171. let h = area(b) - area(bi) - area(bj)
  172. if h > largestWaste:
  173. largestWaste = h
  174. i0 = i
  175. j0 = j
  176. return (i0, j0)
  177. proc pickNext[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; n0, n1, n2: Node[M, D, RT, LT] | Leaf[M, D, RT, LT]; b1, b2: Box[D, RT]): int =
  178. result = 0
  179. let a1 = area(b1)
  180. let a2 = area(b2)
  181. var d = typeof(a1).low
  182. for i in 0 ..< n0.numEntries:
  183. let d1 = area(union(b1, n0.a[i].b)) - a1
  184. let d2 = area(union(b2, n0.a[i].b)) - a2
  185. if (d1 - d2) * (d1 - d2) > d:
  186. result = i
  187. d = (d1 - d2) * (d1 - d2)
  188. from algorithm import SortOrder, sort
  189. proc sortPlus[T](a: var openArray[T], ax: var T, cmp: proc (x, y: T): int {.closure.}, order = algorithm.SortOrder.Ascending) =
  190. var j = 0
  191. let sign = if order == algorithm.SortOrder.Ascending: 1 else: -1
  192. for i in 1 .. a.high:
  193. if cmp(a[i], a[j]) * sign < 0:
  194. j = i
  195. if cmp(a[j], ax) * sign < 0:
  196. swap(ax, a[j])
  197. a.sort(cmp, order)
  198. # R*TREE procs
  199. proc rstarSplit[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; n: var Node[M, D, RT, LT] | var Leaf[M, D, RT, LT]; lx: L[D, RT, LT] | N[M, D, RT, LT]): typeof(n) =
  200. type NL = typeof(lx)
  201. var nBest: typeof(n)
  202. new nBest
  203. var lx = lx
  204. when n is Node[M, D, RT, LT]:
  205. lx.n.parent = n
  206. var lxbest: typeof(lx) = default(typeof(lx))
  207. var m0 = lx.b[0].a.typeof.high
  208. for d2 in 0 ..< 2 * D:
  209. let d = d2 div 2
  210. if d2 mod 2 == 0:
  211. sortPlus(n.a, lx, proc (x, y: NL): int = cmp(x.b[d].a, y.b[d].a))
  212. else:
  213. sortPlus(n.a, lx, proc (x, y: NL): int = cmp(x.b[d].b, y.b[d].b))
  214. for i in t.m - 1 .. n.a.high - t.m + 1:
  215. var b = lx.b
  216. for j in 0 ..< i: # we can precalculate union() for range 0 .. t.m - 1, but that seems to give no real benefit.Maybe for very large M?
  217. #echo "x",j
  218. b = union(n.a[j].b, b)
  219. var m = margin(b)
  220. b = n.a[^1].b
  221. for j in i ..< n.a.high: # again, precalculation of tail would be possible
  222. #echo "y",j
  223. b = union(n.a[j].b, b)
  224. m += margin(b)
  225. if m < m0:
  226. nbest[] = n[]
  227. lxbest = lx
  228. m0 = m
  229. var i0 = -1
  230. var o0 = lx.b[0].a.typeof.high
  231. for i in t.m - 1 .. n.a.typeof.high - t.m + 1:
  232. var b1 = lxbest.b
  233. for j in 0 ..< i:
  234. b1 = union(nbest.a[j].b, b1)
  235. var b2 = nbest.a[^1].b
  236. for j in i ..< n.a.high:
  237. b2 = union(nbest.a[j].b, b2)
  238. let o = overlap(b1, b2)
  239. if o < o0:
  240. i0 = i
  241. o0 = o
  242. n.a[0] = lxbest
  243. for i in 0 ..< i0:
  244. n.a[i + 1] = nbest.a[i]
  245. new result
  246. result.level = n.level
  247. result.parent = n.parent
  248. for i in i0 .. n.a.high:
  249. result.a[i - i0] = nbest.a[i]
  250. n.numEntries = i0 + 1
  251. result.numEntries = M - i0
  252. when n is Node[M, D, RT, LT]:
  253. for i in 0 ..< result.numEntries:
  254. result.a[i].n.parent = result
  255. proc quadraticSplit[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; n: var Node[M, D, RT, LT] | var Leaf[M, D, RT, LT]; lx: L[D, RT, LT] | N[M, D, RT, LT]): typeof(n) =
  256. var n1, n2: typeof(n)
  257. var s1, s2: int
  258. new n1
  259. new n2
  260. n1.parent = n.parent
  261. n2.parent = n.parent
  262. n1.level = n.level
  263. n2.level = n.level
  264. var lx = lx
  265. when n is Node[M, D, RT, LT]:
  266. lx.n.parent = n
  267. (s1, s2) = pickSeeds(t, n, lx.b)
  268. assert s1 >= -1 and s2 >= 0
  269. if unlikely(s1 < 0):
  270. n1.a[0] = lx
  271. else:
  272. n1.a[0] = n.a[s1]
  273. dec(n.numEntries)
  274. if s2 == n.numEntries: # important fix
  275. s2 = s1
  276. n.a[s1] = n.a[n.numEntries]
  277. inc(n1.numEntries)
  278. var b1 = n1.a[0].b
  279. n2.a[0] = n.a[s2]
  280. dec(n.numEntries)
  281. n.a[s2] = n.a[n.numEntries]
  282. inc(n2.numEntries)
  283. var b2 = n2.a[0].b
  284. if s1 >= 0:
  285. n.a[n.numEntries] = lx
  286. inc(n.numEntries)
  287. while n.numEntries > 0 and n1.numEntries < (t.bigM + 1 - t.m) and n2.numEntries < (t.bigM + 1 - t.m):
  288. let next = pickNext(t, n, n1, n2, b1, b2)
  289. let d1 = area(union(b1, n.a[next].b)) - area(b1)
  290. let d2 = area(union(b2, n.a[next].b)) - area(b2)
  291. if (d1 < d2) or (d1 == d2 and ((area(b1) < area(b2)) or (area(b1) == area(b2) and n1.numEntries < n2.numEntries))):
  292. n1.a[n1.numEntries] = n.a[next]
  293. b1 = union(b1, n.a[next].b)
  294. inc(n1.numEntries)
  295. else:
  296. n2.a[n2.numEntries] = n.a[next]
  297. b2 = union(b2, n.a[next].b)
  298. inc(n2.numEntries)
  299. dec(n.numEntries)
  300. n.a[next] = n.a[n.numEntries]
  301. if n.numEntries == 0:
  302. discard
  303. elif n1.numEntries == (t.bigM + 1 - t.m):
  304. while n.numEntries > 0:
  305. dec(n.numEntries)
  306. n2.a[n2.numEntries] = n.a[n.numEntries]
  307. inc(n2.numEntries)
  308. elif n2.numEntries == (t.bigM + 1 - t.m):
  309. while n.numEntries > 0:
  310. dec(n.numEntries)
  311. n1.a[n1.numEntries] = n.a[n.numEntries]
  312. inc(n1.numEntries)
  313. when n is Node[M, D, RT, LT]:
  314. for i in 0 ..< n2.numEntries:
  315. n2.a[i].n.parent = n2
  316. n[] = n1[]
  317. return n2
  318. proc overflowTreatment[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; n: var Node[M, D, RT, LT] | var Leaf[M, D, RT, LT]; lx: L[D, RT, LT] | N[M, D, RT, LT]): typeof(n)
  319. proc adjustTree[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; l, ll: H[M, D, RT, LT]; hb: Box[D, RT]) =
  320. var n = l
  321. var nn = ll
  322. assert n != nil
  323. while true:
  324. if n == t.root:
  325. if nn == nil:
  326. break
  327. t.root = newNode[M, D, RT, LT]()
  328. t.root.level = n.level + 1
  329. Node[M, D, RT, LT](t.root).a[0].n = n
  330. n.parent = t.root
  331. nn.parent = t.root
  332. t.root.numEntries = 1
  333. let p = Node[M, D, RT, LT](n.parent)
  334. var i = 0
  335. while p.a[i].n != n:
  336. inc(i)
  337. var b: typeof(p.a[0].b) = default(typeof(p.a[0].b))
  338. if n of Leaf[M, D, RT, LT]:
  339. when false:#if likely(nn.isNil): # no performance gain
  340. b = union(p.a[i].b, Leaf[M, D, RT, LT](n).a[n.numEntries - 1].b)
  341. else:
  342. b = Leaf[M, D, RT, LT](n).a[0].b
  343. for j in 1 ..< n.numEntries:
  344. b = trtree.union(b, Leaf[M, D, RT, LT](n).a[j].b)
  345. elif n of Node[M, D, RT, LT]:
  346. b = Node[M, D, RT, LT](n).a[0].b
  347. for j in 1 ..< n.numEntries:
  348. b = union(b, Node[M, D, RT, LT](n).a[j].b)
  349. else:
  350. assert false
  351. #if nn.isNil and p.a[i].b == b: break # no performance gain
  352. p.a[i].b = b
  353. n = H[M, D, RT, LT](p)
  354. if unlikely(nn != nil):
  355. if nn of Leaf[M, D, RT, LT]:
  356. b = Leaf[M, D, RT, LT](nn).a[0].b
  357. for j in 1 ..< nn.numEntries:
  358. b = union(b, Leaf[M, D, RT, LT](nn).a[j].b)
  359. elif nn of Node[M, D, RT, LT]:
  360. b = Node[M, D, RT, LT](nn).a[0].b
  361. for j in 1 ..< nn.numEntries:
  362. b = union(b, Node[M, D, RT, LT](nn).a[j].b)
  363. else:
  364. assert false
  365. if p.numEntries < p.a.len:
  366. p.a[p.numEntries].b = b
  367. p.a[p.numEntries].n = nn
  368. inc(p.numEntries)
  369. assert n != nil
  370. nn = nil
  371. else:
  372. let h: N[M, D, RT, LT] = (b, nn)
  373. nn = quadraticSplit(t, p, h)
  374. assert n == H[M, D, RT, LT](p)
  375. assert n != nil
  376. assert t.root != nil
  377. proc insert*[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; leaf: N[M, D, RT, LT] | L[D, RT, LT]; level: int = 0) =
  378. when leaf is N[M, D, RT, LT]:
  379. assert level > 0
  380. type NodeLeaf = Node[M, D, RT, LT]
  381. else:
  382. assert level == 0
  383. type NodeLeaf = Leaf[M, D, RT, LT]
  384. for d in leaf.b:
  385. assert d.a <= d.b
  386. let l = NodeLeaf(chooseSubtree(t, leaf.b, level))
  387. if l.numEntries < l.a.len:
  388. l.a[l.numEntries] = leaf
  389. inc(l.numEntries)
  390. when leaf is N[M, D, RT, LT]:
  391. leaf.n.parent = l
  392. adjustTree(t, l, nil, leaf.b)
  393. else:
  394. let l2 = quadraticSplit(t, l, leaf)
  395. assert l2.level == l.level
  396. adjustTree(t, l, l2, leaf.b)
  397. # R*Tree insert procs
  398. proc rsinsert[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; leaf: N[M, D, RT, LT] | L[D, RT, LT]; level: int)
  399. proc reInsert[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; n: var Node[M, D, RT, LT] | var Leaf[M, D, RT, LT]; lx: L[D, RT, LT] | N[M, D, RT, LT]) =
  400. type NL = typeof(lx)
  401. var lx = lx
  402. var buf: typeof(n.a) = default(typeof(n.a))
  403. let p = Node[M, D, RT, LT](n.parent)
  404. var i = 0
  405. while p.a[i].n != n:
  406. inc(i)
  407. let c = center(p.a[i].b)
  408. sortPlus(n.a, lx, proc (x, y: NL): int = cmp(distance(center(x.b), c), distance(center(y.b), c)))
  409. n.numEntries = M - t.p
  410. swap(n.a[n.numEntries], lx)
  411. inc n.numEntries
  412. var b = n.a[0].b
  413. for i in 1 ..< n.numEntries:
  414. b = union(b, n.a[i].b)
  415. p.a[i].b = b
  416. for i in M - t.p + 1 .. n.a.high:
  417. buf[i] = n.a[i]
  418. rsinsert(t, lx, n.level)
  419. for i in M - t.p + 1 .. n.a.high:
  420. rsinsert(t, buf[i], n.level)
  421. proc overflowTreatment[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; n: var Node[M, D, RT, LT] | var Leaf[M, D, RT, LT]; lx: L[D, RT, LT] | N[M, D, RT, LT]): typeof(n) =
  422. if n.level != t.root.level and t.firstOverflow[n.level]:
  423. t.firstOverflow[n.level] = false
  424. reInsert(t, n, lx)
  425. return nil
  426. else:
  427. let l2 = rstarSplit(t, n, lx)
  428. assert l2.level == n.level
  429. return l2
  430. proc rsinsert[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; leaf: N[M, D, RT, LT] | L[D, RT, LT]; level: int) =
  431. when leaf is N[M, D, RT, LT]:
  432. assert level > 0
  433. type NodeLeaf = Node[M, D, RT, LT]
  434. else:
  435. assert level == 0
  436. type NodeLeaf = Leaf[M, D, RT, LT]
  437. let l = NodeLeaf(chooseSubtree(t, leaf.b, level))
  438. if l.numEntries < l.a.len:
  439. l.a[l.numEntries] = leaf
  440. inc(l.numEntries)
  441. when leaf is N[M, D, RT, LT]:
  442. leaf.n.parent = l
  443. adjustTree(t, l, nil, leaf.b)
  444. else:
  445. when leaf is N[M, D, RT, LT]: # TODO do we need this?
  446. leaf.n.parent = l
  447. let l2 = overflowTreatment(t, l, leaf)
  448. if l2 != nil:
  449. assert l2.level == l.level
  450. adjustTree(t, l, l2, leaf.b)
  451. proc insert*[M, D: Dim; RT, LT](t: RStarTree[M, D, RT, LT]; leaf: L[D, RT, LT]) =
  452. for d in leaf.b:
  453. assert d.a <= d.b
  454. for i in mitems(t.firstOverflow):
  455. i = true
  456. rsinsert(t, leaf, 0)
  457. # delete
  458. proc findLeaf[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; leaf: L[D, RT, LT]): Leaf[M, D, RT, LT] =
  459. proc fl[M, D: Dim; RT, LT](h: H[M, D, RT, LT]; leaf: L[D, RT, LT]): Leaf[M, D, RT, LT] =
  460. var n = h
  461. if n of Node[M, D, RT, LT]:
  462. for i in 0 ..< n.numEntries:
  463. if intersect(Node[M, D, RT, LT](n).a[i].b, leaf.b):
  464. let l = fl(Node[M, D, RT, LT](n).a[i].n, leaf)
  465. if l != nil:
  466. return l
  467. elif n of Leaf[M, D, RT, LT]:
  468. for i in 0 ..< n.numEntries:
  469. if Leaf[M, D, RT, LT](n).a[i] == leaf:
  470. return Leaf[M, D, RT, LT](n)
  471. else:
  472. assert false
  473. return nil
  474. fl(t.root, leaf)
  475. proc condenseTree[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; leaf: Leaf[M, D, RT, LT]) =
  476. var n: H[M, D, RT, LT] = leaf
  477. var q = newSeq[H[M, D, RT, LT]]()
  478. var b: typeof(leaf.a[0].b) = default(typeof(leaf.a[0].b))
  479. while n != t.root:
  480. let p = Node[M, D, RT, LT](n.parent)
  481. var i = 0
  482. while p.a[i].n != n:
  483. inc(i)
  484. if n.numEntries < t.m:
  485. dec(p.numEntries)
  486. p.a[i] = p.a[p.numEntries]
  487. q.add(n)
  488. else:
  489. if n of Leaf[M, D, RT, LT]:
  490. b = Leaf[M, D, RT, LT](n).a[0].b
  491. for j in 1 ..< n.numEntries:
  492. b = union(b, Leaf[M, D, RT, LT](n).a[j].b)
  493. elif n of Node[M, D, RT, LT]:
  494. b = Node[M, D, RT, LT](n).a[0].b
  495. for j in 1 ..< n.numEntries:
  496. b = union(b, Node[M, D, RT, LT](n).a[j].b)
  497. else:
  498. assert false
  499. p.a[i].b = b
  500. n = n.parent
  501. if t of RStarTree[M, D, RT, LT]:
  502. for n in q:
  503. if n of Leaf[M, D, RT, LT]:
  504. for i in 0 ..< n.numEntries:
  505. for i in mitems(RStarTree[M, D, RT, LT](t).firstOverflow):
  506. i = true
  507. rsinsert(RStarTree[M, D, RT, LT](t), Leaf[M, D, RT, LT](n).a[i], 0)
  508. elif n of Node[M, D, RT, LT]:
  509. for i in 0 ..< n.numEntries:
  510. for i in mitems(RStarTree[M, D, RT, LT](t).firstOverflow):
  511. i = true
  512. rsinsert(RStarTree[M, D, RT, LT](t), Node[M, D, RT, LT](n).a[i], n.level)
  513. else:
  514. assert false
  515. else:
  516. for n in q:
  517. if n of Leaf[M, D, RT, LT]:
  518. for i in 0 ..< n.numEntries:
  519. insert(t, Leaf[M, D, RT, LT](n).a[i])
  520. elif n of Node[M, D, RT, LT]:
  521. for i in 0 ..< n.numEntries:
  522. insert(t, Node[M, D, RT, LT](n).a[i], n.level)
  523. else:
  524. assert false
  525. proc delete*[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; leaf: L[D, RT, LT]): bool {.discardable.} =
  526. let l = findLeaf(t, leaf)
  527. if l.isNil:
  528. return false
  529. else:
  530. var i = 0
  531. while l.a[i] != leaf:
  532. inc(i)
  533. dec(l.numEntries)
  534. l.a[i] = l.a[l.numEntries]
  535. condenseTree(t, l)
  536. if t.root.numEntries == 1:
  537. if t.root of Node[M, D, RT, LT]:
  538. t.root = Node[M, D, RT, LT](t.root).a[0].n
  539. t.root.parent = nil
  540. return true
  541. var t = [4, 1, 3, 2]
  542. var xt = 7
  543. sortPlus(t, xt, system.cmp, SortOrder.Ascending)
  544. echo xt, " ", t
  545. type
  546. RSE = L[2, int, int]
  547. RSeq = seq[RSE]
  548. proc rseq_search(rs: RSeq; rse: RSE): seq[int] =
  549. result = newSeq[int]()
  550. for i in rs:
  551. if intersect(i.b, rse.b):
  552. result.add(i.l)
  553. proc rseq_delete(rs: var RSeq; rse: RSE): bool =
  554. result = false
  555. for i in 0 .. rs.high:
  556. if rs[i] == rse:
  557. #rs.delete(i)
  558. rs[i] = rs[rs.high]
  559. rs.setLen(rs.len - 1)
  560. return true
  561. import random, algorithm
  562. proc test(n: int) =
  563. var b: Box[2, int] = default(Box[2, int])
  564. echo center(b)
  565. var x1, x2, y1, y2: int
  566. var t = newRStarTree[8, 2, int, int]()
  567. #var t = newRTree[8, 2, int, int]()
  568. var rs = newSeq[RSE]()
  569. for i in 0 .. 5:
  570. for i in 0 .. n - 1:
  571. x1 = rand(1000)
  572. y1 = rand(1000)
  573. x2 = x1 + rand(25)
  574. y2 = y1 + rand(25)
  575. b = [(x1, x2), (y1, y2)]
  576. let el: L[2, int, int] = (b, i + 7)
  577. t.insert(el)
  578. rs.add(el)
  579. for i in 0 .. (n div 4):
  580. let j = rand(rs.high)
  581. var el = rs[j]
  582. assert t.delete(el)
  583. assert rs.rseq_delete(el)
  584. for i in 0 .. n - 1:
  585. x1 = rand(1000)
  586. y1 = rand(1000)
  587. x2 = x1 + rand(100)
  588. y2 = y1 + rand(100)
  589. b = [(x1, x2), (y1, y2)]
  590. let el: L[2, int, int] = (b, i)
  591. let r = search(t, b)
  592. let r2 = rseq_search(rs, el)
  593. assert r.len == r2.len
  594. assert r.sorted(system.cmp) == r2.sorted(system.cmp)
  595. test(500)