tlc-table-check.scm 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Marcus Crestani, Robert Ransom
  3. (define-test-suite tlc-table-tests)
  4. (define-test-suite tlc-table-weak-tests)
  5. (define-test-suite tlc-table-string-tests)
  6. ;;; most of the test cases are adapted from Eric Knauel's test cases
  7. ;;; he wrote for his id-tables
  8. (define max-table-size 1023)
  9. (define table-step 23)
  10. (define min-collect-times 2)
  11. (define max-collect-times 5)
  12. ;;; helper functions
  13. (define verbose-output? #f)
  14. (define (msg . args)
  15. (if verbose-output?
  16. (begin
  17. (display (apply format args))
  18. (newline))))
  19. (define (collect-n-times n)
  20. (msg "Doing ~a garbage collections" n)
  21. (do-ec (:range k 1 n) (collect)))
  22. (define (random-number a b)
  23. (+ a (random-integer b)))
  24. (define (collect-random-times)
  25. (do-ec (:range k 0 (random-number 5))
  26. (collect)))
  27. (define (random-numbers n a b)
  28. (list-ec (:range i 1 n) (random-number a b)))
  29. (define (random-subset lst)
  30. (let ((len (length lst)))
  31. (list-ec (:list k (random-numbers (random-number 1 len) 0 (- len 1)))
  32. (list-ref lst k))))
  33. (define-record-type rec :rec
  34. (really-make-rec a b)
  35. rec?
  36. (a rec-a set-rec-a!)
  37. (b rec-b))
  38. (define (make-rec)
  39. (really-make-rec (random-value-from-set some-values)
  40. (random-value-from-set some-values)))
  41. (define some-values
  42. (list (lambda () (cons 1 2))
  43. (lambda () 23)
  44. (lambda () #t)
  45. (lambda () #f)
  46. (lambda () 23.42)
  47. (lambda () #\a)
  48. (lambda () 'symbol)
  49. (lambda () (vector 1 2 3))
  50. (lambda () (lambda (x) x))
  51. (lambda () (current-output-port))
  52. (lambda () "Uns ist in alten maeren wunders vil geseit")
  53. (lambda () (make-rec))))
  54. (define some-other-values
  55. (list (lambda () (cons 23 42))
  56. (lambda () 42)
  57. (lambda () #t)
  58. (lambda () #f)
  59. (lambda () 42.23)
  60. (lambda () #\a)
  61. (lambda () 'symbol)
  62. (lambda () (vector 11 12 13))
  63. (lambda () (lambda (y) y))
  64. (lambda () (current-output-port))
  65. (lambda () "Reise, reise, levt das Kottchen, zurrt, zurrt, Hängematten")
  66. (lambda () (make-rec))))
  67. (define (random-value-from-set set)
  68. (let ((max-index (- (length set) 1)))
  69. ((list-ref set (random-integer max-index)))))
  70. (define (random-value)
  71. (random-value-from-set some-values))
  72. (define (random-other-value)
  73. (random-value-from-set some-other-values))
  74. ;;; tests
  75. ;; very basic test
  76. (define-test-case constructor-predicate tlc-table-tests
  77. (check-that
  78. (tlc-table? (make-tlc-table 23))
  79. (is-true)))
  80. ;; create empty tables
  81. (define-test-case empty-tables tlc-table-tests
  82. (do-ec
  83. (:range size 1 max-table-size 64)
  84. (check-that
  85. (tlc-table? (make-tlc-table size))
  86. (is-true))))
  87. ;; create empty tables and collect
  88. (define-test-case empty-tables-collect tlc-table-tests
  89. (do-ec
  90. (:range size 1 max-table-size 64)
  91. (let ((t (make-tlc-table size)))
  92. (collect)
  93. (check-that (tlc-table? t) (is-true)))))
  94. ;; create empty tables and collect n times
  95. (define-test-case empty-tables-collect-n-times tlc-table-tests
  96. (do-ec
  97. (:range size 1 max-table-size table-step)
  98. (let ((t (make-tlc-table size)))
  99. (collect-n-times (random-number min-collect-times max-collect-times))
  100. (check-that (tlc-table? t) (is-true)))))
  101. ;; basic test for set!, contains?, and ref
  102. (define-test-case set/ref tlc-table-tests
  103. (let ((t (make-tlc-table 23))
  104. (obj (cons 1 2)))
  105. (tlc-table-set! t obj obj)
  106. (let ((res-1 (tlc-table-ref t obj #f))
  107. (res-2 (tlc-table-ref t (cons 1 2) #f)))
  108. (check-that (tlc-table-contains? t obj) (is-true))
  109. (check-that (tlc-table-contains? t (cons 1 2)) (is-false))
  110. (check res-1 => obj)
  111. (check-that res-2 (is-false)))))
  112. ;; create empty table and call ref a few times
  113. (define-test-case empty/ref tlc-table-tests
  114. (do-ec
  115. (:range size 1 max-table-size table-step)
  116. (let ((t (make-tlc-table size)))
  117. (do-ec
  118. (:list v some-values)
  119. (begin
  120. (check-that (tlc-table-contains? t (v)) (is-false))
  121. (check-that (tlc-table-ref t (v) #f) (is-false)))))))
  122. ;; create table and fill it a bit
  123. (define-test-case empty/set tlc-table-tests
  124. (do-ec
  125. (:range size 1 max-table-size table-step)
  126. (check-that
  127. (let ((t (make-tlc-table size)))
  128. (do-ec
  129. (:list v some-values)
  130. (tlc-table-set! t (v) (cons 23 42)))
  131. #t)
  132. (is-true))))
  133. ;; create a table, fill it, and read entries
  134. (define-test-case many/set/ref tlc-table-tests
  135. (do-ec
  136. (:range size 1 max-table-size table-step)
  137. (let ((t (make-tlc-table size))
  138. (values (map (lambda (v) (v)) some-values)))
  139. (do-ec
  140. (:list v values)
  141. (begin
  142. (tlc-table-set! t v v)
  143. (check-that (tlc-table-contains? t v) (is-true))
  144. (check (tlc-table-ref t v #f) => v))))))
  145. ;; update one entry multiple times in a row
  146. (define-test-case update-often tlc-table-tests
  147. (let ((t (make-tlc-table 23))
  148. (obj (cons 23 42)))
  149. (do-ec
  150. (:range i 1 1024)
  151. (tlc-table-set! t obj i))
  152. (tlc-table-set! t obj obj)
  153. (check-that (tlc-table-contains? t obj) (is-true))
  154. (check (tlc-table-ref t obj #f) => obj)))
  155. ;; one collection to ref the heap ready for the tests with many
  156. ;; collections
  157. (collect)
  158. ;; create a table with one entry, collect, find it again
  159. (define-test-case set/collect/ref tlc-table-tests
  160. (let ((table (make-tlc-table 23))
  161. (obj (cons 23 42))
  162. (val (cons 65 99)))
  163. (tlc-table-set! table obj val)
  164. (collect)
  165. (check (tlc-table-ref table obj #f) => val)))
  166. ;; fill a table with objects and retrieve them after one collection
  167. (define-test-case set-n/collect/ref-n tlc-table-tests
  168. (do-ec
  169. (:range size 1 max-table-size table-step)
  170. (let* ((table (make-tlc-table size))
  171. (n (* 3 size))
  172. (objs (list-ec (: i n) (cons i n))))
  173. (do-ec
  174. (:list o objs)
  175. (tlc-table-set! table o o))
  176. (collect)
  177. (do-ec
  178. (:list o objs)
  179. (check(tlc-table-ref table o #f) => o)))))
  180. ;; fill a table with objects and retrieve them after n collections
  181. (define-test-case set-n/collect-n/ref-n tlc-table-tests
  182. (do-ec
  183. (:range size 1 max-table-size table-step)
  184. (let* ((table (make-tlc-table size))
  185. (n (* 3 size))
  186. (objs (list-ec (: i n) (cons i n))))
  187. (do-ec
  188. (:list o objs)
  189. (tlc-table-set! table o o))
  190. (collect-n-times (random-number min-collect-times max-collect-times))
  191. (do-ec
  192. (:list o objs)
  193. (check (tlc-table-ref table o #f) => o)))))
  194. ;; create a table with no entry, delete, and try to find it
  195. (define-test-case delete/ref tlc-table-tests
  196. (let ((table (make-tlc-table 23))
  197. (obj (cons 23 42))
  198. (val (cons 65 99)))
  199. (check-that
  200. (tlc-table-delete! table obj #f)
  201. (is-false))
  202. (check-that
  203. (tlc-table-ref table obj #f)
  204. (is-false))))
  205. ;; create a table with one entry, delete, and try to find it again
  206. (define-test-case set/delete/ref tlc-table-tests
  207. (let ((table (make-tlc-table 23))
  208. (obj (cons 23 42))
  209. (val (cons 65 99)))
  210. (tlc-table-set! table obj val)
  211. (check-that
  212. (tlc-table-delete! table obj #f)
  213. (opposite (is-false)))
  214. (check-that
  215. (tlc-table-ref table obj #f)
  216. (is-false))))
  217. ;; create a table with some entries that all go into the same bucket,
  218. ;; delete them, and try to find them again
  219. (define-test-case set-n-in-one-bucket/delete-n/ref-n tlc-table-tests
  220. (let ((table (make-tlc-table 1))
  221. (val (cons 65 99)))
  222. (do-ec
  223. (:range n 1 23)
  224. (tlc-table-set! table n val))
  225. (do-ec
  226. (:range n 1 23)
  227. (check (tlc-table-ref table n #f) => val))
  228. (do-ec
  229. (:range n 1 23)
  230. (check-that
  231. (tlc-table-delete! table n #f)
  232. (opposite (is-false))))
  233. (do-ec
  234. (:range n 1 23)
  235. (check (tlc-table-ref table n #f) => #f))))
  236. ;; create a table with one entry, collect, delete, and try to find it
  237. ;; again
  238. (define-test-case set/collect/delete/ref tlc-table-tests
  239. (let ((table (make-tlc-table 23))
  240. (obj (cons 23 42))
  241. (val (cons 65 99)))
  242. (tlc-table-set! table obj val)
  243. (collect)
  244. (check-that
  245. (tlc-table-delete! table obj #f)
  246. (opposite (is-false)))
  247. (check-that
  248. (tlc-table-ref table obj #f)
  249. (is-false))))
  250. ;; fill a table with objects, delete some, and retrieve them
  251. (define-test-case set-n/delete-n/ref-n tlc-table-tests
  252. (do-ec
  253. (:range size 1 max-table-size table-step)
  254. (let* ((table (make-tlc-table size))
  255. (n (* 3 size))
  256. (objs (list-ec (: i n) (cons i n)))
  257. (delobjs (list-ec (: i n) (cons (+ i max-table-size) n))))
  258. (do-ec
  259. (:list o delobjs)
  260. (tlc-table-set! table o o))
  261. (do-ec
  262. (:list o objs)
  263. (tlc-table-set! table o o))
  264. (do-ec
  265. (:list o delobjs)
  266. (check-that
  267. (tlc-table-delete! table o #f)
  268. (opposite (is-false))))
  269. (do-ec
  270. (:list o delobjs)
  271. (check-that
  272. (tlc-table-ref table o #f)
  273. (is-false)))
  274. (do-ec
  275. (:list o objs)
  276. (check (tlc-table-ref table o #f) => o)))))
  277. ;; fill a table with objects, delete some, and retrieve them after one
  278. ;; collection
  279. (define-test-case set-n/collect/delete-n/ref-n tlc-table-tests
  280. (do-ec
  281. (:range size 1 max-table-size table-step)
  282. (let* ((table (make-tlc-table size))
  283. (n (* 3 size))
  284. (objs (list-ec (: i n) (cons i n)))
  285. (delobjs (list-ec (: i n) (cons (+ i max-table-size) n))))
  286. (do-ec
  287. (:list o delobjs)
  288. (tlc-table-set! table o o))
  289. (collect)
  290. (do-ec
  291. (:list o objs)
  292. (tlc-table-set! table o o))
  293. (collect)
  294. (do-ec
  295. (:list o delobjs)
  296. (check-that
  297. (tlc-table-delete! table o #f)
  298. (opposite (is-false))))
  299. (collect)
  300. (do-ec
  301. (:list o delobjs)
  302. (check-that
  303. (tlc-table-ref table o #f)
  304. (is-false)))
  305. (do-ec
  306. (:list o objs)
  307. (check (tlc-table-ref table o #f) => o)))))
  308. ;; fill a table with objects, delete some, and retrieve the others
  309. ;; after n collections
  310. (define-test-case set-n/collect-n/delete-n/ref-n tlc-table-tests
  311. (do-ec
  312. (:range size 1 max-table-size table-step)
  313. (let* ((table (make-tlc-table size))
  314. (n (* 3 size))
  315. (objs (list-ec (: i n) (cons i n)))
  316. (delobjs (list-ec (: i n) (cons i n))))
  317. (do-ec
  318. (:list o delobjs)
  319. (tlc-table-set! table o o))
  320. (collect-n-times (random-number min-collect-times max-collect-times))
  321. (do-ec
  322. (:list o objs)
  323. (tlc-table-set! table o o))
  324. (collect-n-times (random-number min-collect-times max-collect-times))
  325. (do-ec
  326. (:list o delobjs)
  327. (check-that
  328. (tlc-table-delete! table o #f)
  329. (opposite (is-false))))
  330. (collect-n-times (random-number min-collect-times max-collect-times))
  331. (do-ec
  332. (:list o delobjs)
  333. (check-that
  334. (tlc-table-ref table o #f)
  335. (is-false)))
  336. (do-ec
  337. (:list o objs)
  338. (check (tlc-table-ref table o #f) => o)))))
  339. ;; helper function for checking entries: check if the order and number
  340. ;; of keys and values returned by tlc-table-entries is correct.
  341. (define (check-entries t n)
  342. (call-with-values
  343. (lambda ()
  344. (tlc-table-entries t))
  345. (lambda (keys values)
  346. (for-each
  347. (lambda (key value)
  348. (check (tlc-table-ref t key #f)
  349. => value))
  350. (vector->list keys)
  351. (vector->list values))
  352. (check
  353. (vector-length keys)
  354. => (vector-length (tlc-table-keys t)))
  355. (check
  356. (vector-length keys)
  357. => (tlc-table-size t))
  358. (check (tlc-table-size t) => n))))
  359. ;; check entries for empty tables
  360. (define-test-case empty-entries tlc-table-tests
  361. (do-ec
  362. (:range size 1 max-table-size table-step)
  363. (let ((t (make-tlc-table size)))
  364. (check-entries t 0))))
  365. ;; check entries for one-element tables
  366. (define-test-case one-element-entries tlc-table-tests
  367. (do-ec
  368. (:range size 1 max-table-size table-step)
  369. (let ((t (make-tlc-table size))
  370. (p (cons 23 42)))
  371. (tlc-table-set! t p p)
  372. (check-entries t 1))))
  373. ;; check entries for filled tables (unmovable keys)
  374. (define-test-case set-entries/unmovable tlc-table-tests
  375. (do-ec
  376. (:range size 1 (quotient max-table-size 3) table-step)
  377. (let ((t (make-tlc-table size)))
  378. (check-entries t 0)
  379. (do-ec
  380. (:range i 1 (* 3 size))
  381. (begin
  382. (tlc-table-set! t i (cons i i))
  383. (check-entries t i))))))
  384. ;; check entries with set and delete (unmovable keys)
  385. (define-test-case set-delete-entries/unmovable tlc-table-tests
  386. (do-ec
  387. (:range size 1 (quotient max-table-size 3) table-step)
  388. (let ((t (make-tlc-table size)))
  389. (check-entries t 0)
  390. (do-ec
  391. (:range i 1 (* 3 size))
  392. (begin
  393. (tlc-table-set! t i (cons i i))
  394. (tlc-table-set! t (+ i (* 3 size)) (cons i i))
  395. (check-that (tlc-table-delete! t i #f)
  396. (opposite (is-false)))
  397. (check-entries t i))))))
  398. ;; check entries with set, delete, and clear (unmovable keys)
  399. (define-test-case set-delete-clear-entries/unmovable tlc-table-tests
  400. (do-ec
  401. (:range size 1 (quotient max-table-size 3) table-step)
  402. (let ((t (make-tlc-table size)))
  403. (check-entries t 0)
  404. (do-ec
  405. (:range i 1 (* 3 size))
  406. (begin
  407. (tlc-table-clear! t)
  408. (check (tlc-table-size t) => 0)
  409. (tlc-table-set! t i (cons i i))
  410. (tlc-table-set! t (+ i (* 3 size)) (cons i i))
  411. (check-that (tlc-table-delete! t i #f)
  412. (opposite (is-false)))
  413. (check-entries t 1))))))
  414. ;; check entries for filled and cleared tables
  415. (define-test-case set-entries tlc-table-tests
  416. (do-ec
  417. (:range size 1 (quotient max-table-size 3) table-step)
  418. (let ((t (make-tlc-table size)))
  419. (tlc-table-clear! t)
  420. (check-entries t 0)
  421. (do-ec
  422. (:range i 1 (* 3 size))
  423. (begin
  424. (tlc-table-set! t (cons i i) (cons i i))
  425. (check-entries t i))))))
  426. ;; fill a table with objects, delete some, and retrieve the others
  427. ;; after n collections
  428. (define-test-case set-collect-delete-entries tlc-table-tests
  429. (do-ec
  430. (:range size 1 (quotient max-table-size 3) table-step)
  431. (let* ((t (make-tlc-table size))
  432. (n (* 3 size))
  433. (objs (list-ec (: i n) (cons i n)))
  434. (delobjs (list-ec (: i n) (cons i n))))
  435. (do-ec
  436. (:list o delobjs)
  437. (tlc-table-set! t o o))
  438. (check-entries t n)
  439. (collect-n-times (random-number min-collect-times max-collect-times))
  440. (do-ec
  441. (:list o objs)
  442. (tlc-table-set! t o o))
  443. (check-entries t (* 2 n))
  444. (collect-n-times (random-number min-collect-times max-collect-times))
  445. (do-ec
  446. (:list o delobjs)
  447. (check-that
  448. (tlc-table-delete! t o #f)
  449. (opposite (is-false))))
  450. (check-entries t n)
  451. (collect-n-times (random-number min-collect-times max-collect-times))
  452. (do-ec
  453. (:list o delobjs)
  454. (check-that
  455. (tlc-table-ref t o #f)
  456. (is-false)))
  457. (check-entries t n)
  458. (do-ec
  459. (:list o objs)
  460. (check (tlc-table-ref t o #f) => o))
  461. (check-entries t n))))
  462. ;; WEAK TESTS
  463. ;; create a table with one weak entry and find it again
  464. (define-test-case weak-set/ref tlc-table-weak-tests
  465. (let* ((table (make-tlc-table 23))
  466. (obj (cons 23 42))
  467. (wp (make-weak-pointer obj))
  468. (val (cons 65 99)))
  469. (tlc-table-set! table wp val)
  470. (check (tlc-table-ref table wp #f) => val)))
  471. ;; create a table with one weak entry, collect and find it again
  472. (define-test-case weak-set/collect/ref tlc-table-weak-tests
  473. (let* ((table (make-tlc-table 23))
  474. (obj (cons 23 42))
  475. (wp (make-weak-pointer obj))
  476. (val (cons 65 99)))
  477. (tlc-table-set! table wp val)
  478. (collect)
  479. (check (tlc-table-ref table wp #f) => val)))
  480. ;; fill a table with weak objects and retrieve them after one
  481. ;; collection
  482. (define-test-case weak-set-n/collect/ref-n tlc-table-weak-tests
  483. (do-ec
  484. (:range size 1 max-table-size table-step)
  485. (let* ((table (make-tlc-table size))
  486. (n (* 3 size))
  487. (objs (list-ec (: i n) (cons i n)))
  488. (wobjs (map make-weak-pointer objs)))
  489. (do-ec
  490. (:list o wobjs)
  491. (tlc-table-set! table o o))
  492. (collect)
  493. (do-ec
  494. (:list o wobjs)
  495. (check (tlc-table-ref table o #f) => o)))))
  496. ;; fill a table with weak objects and retrieve them after n
  497. ;; collections
  498. (define-test-case weak-set-n/collect-n/ref-n tlc-table-weak-tests
  499. (do-ec
  500. (:range size 1 max-table-size table-step)
  501. (let* ((table (make-tlc-table size))
  502. (n (* 3 size))
  503. (objs (list-ec (: i n) (cons i n)))
  504. (wobjs (map make-weak-pointer objs)))
  505. (do-ec
  506. (:list o wobjs)
  507. (tlc-table-set! table o o))
  508. (collect-n-times (random-number min-collect-times max-collect-times))
  509. (do-ec
  510. (:list o wobjs)
  511. (check (tlc-table-ref table o #f) => o)))))
  512. ;; create a table with no weak entry, delete, and try to find it
  513. (define-test-case weak-delete/ref tlc-table-weak-tests
  514. (let* ((table (make-tlc-table 23))
  515. (obj (cons 23 42))
  516. (wobj (make-weak-pointer obj))
  517. (val (cons 65 99)))
  518. (check-that
  519. (tlc-table-delete! table wobj #f)
  520. (is-false))
  521. (check-that
  522. (tlc-table-ref table wobj #f)
  523. (is-false))))
  524. ;; create a table with one weak entry, delete, and try to find it
  525. ;; again
  526. (define-test-case weak-set/delete/ref tlc-table-weak-tests
  527. (let* ((table (make-tlc-table 23))
  528. (obj (cons 23 42))
  529. (wobj (make-weak-pointer obj))
  530. (val (cons 65 99)))
  531. (tlc-table-set! table wobj val)
  532. (check-that
  533. (tlc-table-delete! table wobj #f)
  534. (opposite (is-false)))
  535. (check-that
  536. (tlc-table-ref table wobj #f)
  537. (is-false))))
  538. ;; create a table with one weak entry, collect, delete, and try to
  539. ;; find it again
  540. (define-test-case weak-set/collect/delete/ref tlc-table-weak-tests
  541. (let* ((table (make-tlc-table 23))
  542. (obj (cons 23 42))
  543. (wobj (make-weak-pointer obj))
  544. (val (cons 65 99)))
  545. (tlc-table-set! table wobj val)
  546. (collect)
  547. (check-that
  548. (tlc-table-delete! table wobj #f)
  549. (opposite (is-false)))
  550. (check-that
  551. (tlc-table-ref table wobj #f)
  552. (is-false))))
  553. ;; fill a table with weak objects, delete some, and retrieve the
  554. ;; others after one collection
  555. (define-test-case weak-set-n/collect/delete-n/ref-n tlc-table-weak-tests
  556. (do-ec
  557. (:range size 1 max-table-size table-step)
  558. (let* ((table (make-tlc-table size))
  559. (n (* 3 size))
  560. (objs (list-ec (: i n) (cons i n)))
  561. (wobjs (map make-weak-pointer objs))
  562. (delobjs (list-ec (: i n) (cons (+ i 100) 42)))
  563. (delwobjs (map make-weak-pointer delobjs)))
  564. (do-ec
  565. (:list o wobjs)
  566. (tlc-table-set! table o o))
  567. (do-ec
  568. (:list o delwobjs)
  569. (tlc-table-set! table o o))
  570. (do-ec
  571. (:list o delwobjs)
  572. (check (tlc-table-ref table o #f) => o))
  573. (do-ec
  574. (:list o wobjs)
  575. (check (tlc-table-ref table o #f) => o))
  576. (collect)
  577. (do-ec
  578. (:list o delwobjs)
  579. (check-that
  580. (tlc-table-delete! table o #f)
  581. (opposite (is-false))))
  582. (do-ec
  583. (:list o delwobjs)
  584. (check-that
  585. (tlc-table-ref table o #f)
  586. (is-false)))
  587. (do-ec
  588. (:list o wobjs)
  589. (check (tlc-table-ref table o #f) => o)))))
  590. ;; fill a table with weak objects, delete some, and retrieve the
  591. ;; others after n collections
  592. (define-test-case weak-set-n/collect-n/delete-n/ref-n tlc-table-weak-tests
  593. (do-ec
  594. (:range size 1 max-table-size table-step)
  595. (let* ((table (make-tlc-table size))
  596. (n (* 3 size))
  597. (objs (list-ec (: i n) (cons i n)))
  598. (wobjs (map make-weak-pointer objs))
  599. (delobjs (list-ec (: i n) (cons (+ i 100) 42)))
  600. (delwobjs (map make-weak-pointer delobjs)))
  601. (do-ec
  602. (:list o wobjs)
  603. (tlc-table-set! table o o))
  604. (do-ec
  605. (:list o delwobjs)
  606. (tlc-table-set! table o o))
  607. (collect-n-times (random-number min-collect-times max-collect-times))
  608. (do-ec
  609. (:list o delwobjs)
  610. (check-that
  611. (tlc-table-delete! table o #f)
  612. (opposite (is-false))))
  613. (do-ec
  614. (:list o wobjs)
  615. (check (tlc-table-ref table o #f) => o))
  616. (do-ec
  617. (:list o delwobjs)
  618. (check-that
  619. (tlc-table-ref table o #f)
  620. (is-false))))))
  621. ;; fill a table with weak objects, delete some, and
  622. ;; retrieve the others after n collections
  623. (define-test-case weak-set-collect-delete-entries tlc-table-weak-tests
  624. (do-ec
  625. (:range size 1 (quotient max-table-size 3) table-step)
  626. (let* ((t (make-tlc-table size))
  627. (n (* 3 size))
  628. (objs (list-ec (: i n) (cons i n)))
  629. (delobjs (list-ec (: i n) (cons i n)))
  630. (wobjs (map make-weak-pointer objs))
  631. (delwobjs (map make-weak-pointer delobjs)))
  632. (do-ec
  633. (:list o delwobjs)
  634. (tlc-table-set! t o o))
  635. (check-entries t n)
  636. (collect-n-times (random-number min-collect-times max-collect-times))
  637. (do-ec
  638. (:list o wobjs)
  639. (tlc-table-set! t o o))
  640. (check-entries t (* 2 n))
  641. (collect-n-times (random-number min-collect-times max-collect-times))
  642. (do-ec
  643. (:list o delwobjs)
  644. (check-that
  645. (tlc-table-delete! t o #f)
  646. (opposite (is-false))))
  647. (check-entries t n)
  648. (collect-n-times (random-number min-collect-times max-collect-times))
  649. (do-ec
  650. (:list o delwobjs)
  651. (check-that
  652. (tlc-table-ref t o #f)
  653. (is-false)))
  654. (check-entries t n)
  655. (do-ec
  656. (:list o wobjs)
  657. (check (tlc-table-ref t o #f) => o))
  658. (check-entries t n))))
  659. ;; string table with strings as keys
  660. (define-test-case string-table tlc-table-string-tests
  661. (let* ((t (make-non-default-tlc-table string-hash string= 23 #f)))
  662. (tlc-table-set! t "Key" "Value")
  663. (check (tlc-table-ref t "Key" #f) => "Value")
  664. (check-that (tlc-table-ref t "Value" #f) (is-false))))
  665. ; eqv? table with various objects as keys
  666. (define-test-case eqv-table tlc-table-tests
  667. (let ((t (make-eqv-tlc-table 23))
  668. (ns '(1 10 100 1000 10000 100000)) ; must not contain 0
  669. (ms '(1 10 100 1000))) ; (exp 1000) is infinite
  670. ; initialize table
  671. (let-syntax ((stuff-table
  672. (syntax-rules ()
  673. ((stuff-table xs var expr)
  674. (for-each (lambda (x)
  675. (tlc-table-set! t (let ((var x)) expr) x))
  676. xs)))))
  677. (stuff-table ns n (expt 2 n))
  678. (stuff-table ns n (/ (expt 3 n) (expt 2 n)))
  679. (stuff-table ns n (+ (expt 2 n) (* 0+1i (expt 3 n))))
  680. (stuff-table ms n (exp n))
  681. (stuff-table ns n (exp (* n 0+1i)))
  682. (stuff-table ns n (make-string n #\x)))
  683. ; check its contents
  684. (let-syntax ((check-stuffed
  685. (syntax-rules ()
  686. ((check-stuffed xs var expr)
  687. (for-each (lambda (x)
  688. (check
  689. (tlc-table-ref t (let ((var x)) expr) #f)
  690. => x))
  691. xs))))
  692. (check-not-stuffed
  693. (syntax-rules ()
  694. ((check-not-stuffed xs var expr)
  695. (for-each (lambda (x)
  696. (check
  697. (tlc-table-ref t (let ((var x)) expr) #f)
  698. => #f))
  699. xs)))))
  700. (check-stuffed ns n (expt 2 n))
  701. (check-stuffed ns n (/ (expt 3 n) (expt 2 n)))
  702. (check-stuffed ns n (+ (expt 2 n) (* 0+1i (expt 3 n))))
  703. (check-stuffed ms n (exp n))
  704. (check-stuffed ns n (exp (* n 0+1i)))
  705. (check-not-stuffed ns n (expt 3 n))
  706. (check-not-stuffed ns n (/ (expt 2 n) (expt 3 n)))
  707. (check-not-stuffed ns n (+ (expt 3 n) (* 0+1i (expt 2 n))))
  708. (check-not-stuffed ms n (exp (- n)))
  709. (check-not-stuffed ns n (exp (* n 0-1i)))
  710. (check-not-stuffed ns n (make-string n #\x))))) ; not eqv? to the strings above
  711. (define-test-case has-tconc-queue? tlc-table-tests
  712. (check
  713. (tlc-table-has-tconc-queue? (make-eq-tlc-table 23))
  714. => #t)
  715. (check
  716. (tlc-table-has-tconc-queue? (make-eqv-tlc-table 23))
  717. => #t)
  718. (check
  719. (tlc-table-has-tconc-queue?
  720. (make-non-default-tlc-table string-hash string=? 23 #f))
  721. => #f))