main.c 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413
  1. // # ifdef __cplusplus
  2. // extern "C" {
  3. // # endif
  4. //========================================================================================================================================================================================================200
  5. //======================================================================================================================================================150
  6. //====================================================================================================100
  7. //==================================================50
  8. //========================================================================================================================================================================================================200
  9. // INFORMATION
  10. //========================================================================================================================================================================================================200
  11. //======================================================================================================================================================150
  12. // UPDATE
  13. //======================================================================================================================================================150
  14. // 2009; Amittai Aviram; entire code written in C;
  15. // 2010; Jordan Fix and Andrew Wilkes; code converted to CUDA;
  16. // 2011.10; Lukasz G. Szafaryn; code converted to portable form, to C, OpenMP, CUDA, PGI versions;
  17. // 2011.12; Lukasz G. Szafaryn; Split different versions for Rodinia.
  18. // 2011.12; Lukasz G. Szafaryn; code converted to OpenCL;
  19. //======================================================================================================================================================150
  20. // DESCRIPTION
  21. //======================================================================================================================================================150
  22. // Description
  23. //======================================================================================================================================================150
  24. // USE
  25. //======================================================================================================================================================150
  26. // EXAMPLE:
  27. // ./a.out -file ./input/mil.txt
  28. // ...then enter any of the following commands after the prompt > :
  29. // f <x> -- Find the value under key <x>
  30. // p <x> -- Print the path from the root to key k and its associated value
  31. // t -- Print the B+ tree
  32. // l -- Print the keys of the leaves (bottom row of the tree)
  33. // v -- Toggle output of pointer addresses ("verbose") in tree and leaves.
  34. // k <x> -- Run <x> bundled queries on the CPU and GPU (B+Tree) (Selects random values for each search)
  35. // j <x> <y> -- Run a range search of <x> bundled queries on the CPU and GPU (B+Tree) with the range of each search of size <y>
  36. // x <z> -- Run a single search for value z on the GPU and CPU
  37. // y <a> <b> -- Run a single range search for range a-b on the GPU and CPU
  38. // q -- Quit. (Or use Ctl-D.)
  39. //======================================================================================================================================================150
  40. // END
  41. //======================================================================================================================================================150
  42. //========================================================================================================================================================================================================200
  43. // DEFINE/INCLUDE
  44. //========================================================================================================================================================================================================200
  45. //======================================================================================================================================================150
  46. // LIBRARIES
  47. //======================================================================================================================================================150
  48. #include <stdio.h> // (in directory known to compiler) needed by printf, stderr
  49. #include <limits.h> // (in directory known to compiler) needed by INT_MIN, INT_MAX
  50. // #include <sys/time.h> // (in directory known to compiler) needed by ???
  51. #include <math.h> // (in directory known to compiler) needed by log, pow
  52. #include <string.h> // (in directory known to compiler) needed by memset
  53. //======================================================================================================================================================150
  54. // COMMON
  55. //======================================================================================================================================================150
  56. #include "./common.h" // (in directory provided here)
  57. //======================================================================================================================================================150
  58. // DEFINE
  59. //======================================================================================================================================================150
  60. //======================================================================================================================================================150
  61. // UTILITIES
  62. //======================================================================================================================================================150
  63. #include "./util/timer/timer.h" // (in directory provided here)
  64. #include "./util/num/num.h" // (in directory provided here)
  65. //======================================================================================================================================================150
  66. // KERNEL HEADERS
  67. //======================================================================================================================================================150
  68. #include "./kernel/kernel_gpu_opencl_wrapper.h" // (in directory provided here)
  69. #include "./kernel/kernel_gpu_opencl_wrapper_2.h" // (in directory provided here)
  70. //======================================================================================================================================================150
  71. // HEADER
  72. //======================================================================================================================================================150
  73. #include "./main.h" // (in directory provided here)
  74. //======================================================================================================================================================150
  75. // END
  76. //======================================================================================================================================================150
  77. //========================================================================================================================================================================================================200
  78. // VARIABLES
  79. //========================================================================================================================================================================================================200
  80. // general variables
  81. knode *knodes;
  82. record *krecords;
  83. char *mem;
  84. long freeptr;
  85. long malloc_size;
  86. long size;
  87. long maxheight;
  88. /* The order determines the maximum and minimum
  89. * number of entries (keys and pointers) in any
  90. * node. Every node has at most order - 1 keys and
  91. * at least (roughly speaking) half that number.
  92. * Every leaf has as many pointers to data as keys,
  93. * and every internal node has one more pointer
  94. * to a subtree than the number of keys.
  95. * This global variable is initialized to the
  96. * default value.
  97. */
  98. int order = DEFAULT_ORDER;
  99. /* The queue is used to print the tree in
  100. * level order, starting from the root
  101. * printing each entire rank on a separate
  102. * line, finishing with the leaves.
  103. */
  104. node *queue = NULL;
  105. /* The user can toggle on and off the "verbose"
  106. * property, which causes the pointer addresses
  107. * to be printed out in hexadecimal notation
  108. * next to their corresponding keys.
  109. */
  110. bool verbose_output = false;
  111. //========================================================================================================================================================================================================200
  112. // FUNCTIONS
  113. //========================================================================================================================================================================================================200
  114. //======================================================================================================================================================150
  115. // Components
  116. //======================================================================================================================================================150
  117. void
  118. list_init( list_t *l,
  119. int32_t (*compare)(const void *key,
  120. const void *with),
  121. void (*datum_delete)(void *))
  122. {
  123. l->head = l->tail = NULL;
  124. l->length = 0;
  125. l->compare = compare;
  126. l->datum_delete = datum_delete;
  127. }
  128. void
  129. list_delete(list_t *l)
  130. {
  131. list_item_t *li, *del;
  132. for (li = l->head; li;) {
  133. del = li;
  134. li = li->next;
  135. list_item_delete(del, l->datum_delete);
  136. }
  137. l->head = l->tail = NULL;
  138. l->length = 0;
  139. }
  140. void
  141. list_reset(list_t *l)
  142. {
  143. list_delete(l);
  144. }
  145. void
  146. list_insert_item_head( list_t *l,
  147. list_item_t *i)
  148. {
  149. if (l->head) {
  150. i->next = l->head;
  151. l->head->pred = i;
  152. l->head = i;
  153. l->head->pred = NULL;
  154. } else {
  155. l->head = l->tail = i;
  156. i->next = i->pred = NULL;
  157. }
  158. l->length++;
  159. }
  160. void
  161. list_insert_item_tail( list_t *l,
  162. list_item_t *i)
  163. {
  164. if (l->head) {
  165. l->tail->next = i;
  166. i->pred = l->tail;
  167. i->next = NULL;
  168. l->tail = i;
  169. } else {
  170. l->head = l->tail = i;
  171. i->next = i->pred = NULL;
  172. }
  173. l->length++;
  174. }
  175. void
  176. list_insert_item_before(list_t *l,
  177. list_item_t *next,
  178. list_item_t *i)
  179. {
  180. /* Assume next is actually in the list! */
  181. /* If it's not, we may lose the list. */
  182. if (l->head == next) {
  183. i->next = next;
  184. i->pred = NULL;
  185. l->head = i;
  186. next->pred = i;
  187. } else {
  188. i->next = next;
  189. i->pred = next->pred;
  190. next->pred->next = i;
  191. next->pred = i;
  192. }
  193. l->length++;
  194. }
  195. void
  196. list_insert_item_after( list_t *l,
  197. list_item_t *pred,
  198. list_item_t *i)
  199. {
  200. /* Assume pred is actually in the list! */
  201. /* If it's not, we may lose the list. */
  202. if (l->tail == pred) {
  203. i->pred = pred;
  204. i->next = NULL;
  205. l->tail = i;
  206. pred->next = i;
  207. } else {
  208. i->pred = pred;
  209. i->next = pred->next;
  210. pred->next->pred = i;
  211. pred->next = i;
  212. }
  213. l->length++;
  214. }
  215. void
  216. list_insert_item_sorted(list_t *l,
  217. list_item_t *i)
  218. {
  219. list_item_t *itr;
  220. if (l->head) {
  221. for (itr = l->head; itr && l->compare(list_item_get_datum(i),
  222. list_item_get_datum(itr)) < 0;
  223. itr = itr->next)
  224. ;
  225. if (itr) {
  226. i->next = itr;
  227. i->pred = itr->pred;
  228. itr->pred = i;
  229. i->pred->next = i;
  230. } else {
  231. l->tail->next = i;
  232. i->pred = l->tail;
  233. i->next = NULL;
  234. l->tail = i;
  235. }
  236. } else {
  237. l->head = l->tail = i;
  238. i->pred = i->next = NULL;
  239. }
  240. l->length++;
  241. }
  242. void
  243. list_insert_head( list_t *l,
  244. void *v)
  245. {
  246. list_item_t *i;
  247. i = (list_item_t *)malloc(sizeof (*i));
  248. list_item_init(i, v);
  249. if (l->head) {
  250. i->next = l->head;
  251. l->head->pred = i;
  252. l->head = i;
  253. l->head->pred = NULL;
  254. } else {
  255. l->head = l->tail = i;
  256. i->next = i->pred = NULL;
  257. }
  258. l->length++;
  259. }
  260. void
  261. list_insert_tail( list_t *l,
  262. void *v)
  263. {
  264. list_item_t *i;
  265. i = (list_item_t *)malloc(sizeof (*i));
  266. list_item_init(i, v);
  267. if (l->head) {
  268. l->tail->next = i;
  269. i->pred = l->tail;
  270. i->next = NULL;
  271. l->tail = i;
  272. } else {
  273. l->head = l->tail = i;
  274. i->next = i->pred = NULL;
  275. }
  276. l->length++;
  277. }
  278. void
  279. list_insert_before( list_t *l,
  280. list_item_t *next,
  281. void *v)
  282. {
  283. list_item_t *i;
  284. i = (list_item_t *)malloc(sizeof (*i));
  285. list_item_init(i, v);
  286. /* Assume next is actually in the list! */
  287. /* If it's not, we may lose the list. */
  288. if (l->head == next) {
  289. i->next = next;
  290. i->pred = NULL;
  291. l->head = i;
  292. next->pred = i;
  293. } else {
  294. i->next = next;
  295. i->pred = next->pred;
  296. next->pred->next = i;
  297. next->pred = i;
  298. }
  299. l->length++;
  300. }
  301. void
  302. list_insert_after( list_t *l,
  303. list_item_t *pred,
  304. void *v)
  305. {
  306. list_item_t *i;
  307. i = (list_item_t *)malloc(sizeof (*i));
  308. list_item_init(i, v);
  309. /* Assume pred is actually in the list! */
  310. /* If it's not, we may lose the list. */
  311. if (l->tail == pred) {
  312. i->pred = pred;
  313. i->next = NULL;
  314. l->tail = i;
  315. pred->next = i;
  316. } else {
  317. i->pred = pred;
  318. i->next = pred->next;
  319. pred->next->pred = i;
  320. pred->next = i;
  321. }
  322. l->length++;
  323. }
  324. void
  325. list_insert_sorted( list_t *l,
  326. void *v)
  327. {
  328. list_item_t *itr;
  329. list_item_t *i;
  330. i = (list_item_t *)malloc(sizeof (*i));
  331. list_item_init(i, v);
  332. if (l->head) {
  333. for (itr = l->head; itr && l->compare(list_item_get_datum(i),
  334. list_item_get_datum(itr)) < 0;
  335. itr = itr->next)
  336. ;
  337. if (itr) {
  338. i->next = itr;
  339. i->pred = itr->pred;
  340. itr->pred = i;
  341. i->pred->next = i;
  342. } else {
  343. l->tail->next = i;
  344. i->pred = l->tail;
  345. i->next = NULL;
  346. l->tail = i;
  347. }
  348. } else {
  349. l->head = l->tail = i;
  350. i->pred = i->next = NULL;
  351. }
  352. l->length++;
  353. }
  354. void
  355. list_remove_item( list_t *l,
  356. list_item_t *i)
  357. {
  358. if (i == l->head) {
  359. l->head = l->head->next;
  360. if (l->head)
  361. l->head->pred = NULL;
  362. else
  363. l->tail = NULL;
  364. } else if (i == l->tail) {
  365. l->tail = l->tail->pred;
  366. l->tail->next = NULL;
  367. } else {
  368. i->pred->next = i->next;
  369. i->next->pred = i->pred;
  370. }
  371. l->length--;
  372. list_item_delete(i, l->datum_delete);
  373. }
  374. void
  375. list_remove_head(list_t *l)
  376. {
  377. list_remove_item(l, l->head);
  378. }
  379. void
  380. list_remove_tail(list_t *l)
  381. {
  382. list_remove_item(l, l->tail);
  383. }
  384. list_item_t*
  385. list_find_item( list_t *l,
  386. void *datum)
  387. {
  388. list_item_t *li;
  389. for (li = l->head; li && l->compare(datum, list_item_get_datum(li));
  390. li = li->next)
  391. ;
  392. return li;
  393. }
  394. list_item_t*
  395. list_get_head_item(list_t *l)
  396. {
  397. return l->head;
  398. }
  399. list_item_t*
  400. list_get_tail_item(list_t *l)
  401. {
  402. return l->tail;
  403. }
  404. void*
  405. list_find( list_t *l,
  406. void *datum)
  407. {
  408. list_item_t *li;
  409. for (li = l->head; li && l->compare(datum, list_item_get_datum(li));
  410. li = li->next)
  411. ;
  412. return li ? li->datum : NULL;
  413. }
  414. void*
  415. list_get_head(list_t *l)
  416. {
  417. return l->head ? l->head->datum : NULL;
  418. }
  419. void*
  420. list_get_tail(list_t *l)
  421. {
  422. return l->tail ? l->tail->datum : NULL;
  423. }
  424. uint32_t
  425. list_get_length(list_t *l)
  426. {
  427. return l->length;
  428. }
  429. bool
  430. list_is_empty(list_t *l)
  431. {
  432. return (l->length == 0);
  433. }
  434. bool
  435. list_not_empty(list_t *l)
  436. {
  437. return (l->length != 0);
  438. }
  439. void
  440. list_visit_items( list_t *l,
  441. void (*visitor)(void *v))
  442. {
  443. list_item_t *li;
  444. for (li = l->head; li; li = li->next)
  445. visitor(list_item_get_datum(li));
  446. }
  447. void
  448. list_item_init( list_item_t *li,
  449. void *datum)
  450. {
  451. li->pred = li->next = NULL;
  452. li->datum = datum;
  453. }
  454. void
  455. list_item_delete( list_item_t *li,
  456. void (*datum_delete)(void *datum))
  457. {
  458. if (datum_delete) {
  459. datum_delete(li->datum);
  460. }
  461. free(li);
  462. }
  463. void *
  464. list_item_get_datum(list_item_t *li)
  465. {
  466. return li->datum;
  467. }
  468. void
  469. list_iterator_init( list_t *l,
  470. list_iterator_t *li)
  471. {
  472. *li = l ? l->head : NULL;
  473. }
  474. void
  475. list_iterator_delete(list_iterator_t *li)
  476. {
  477. *li = NULL;
  478. }
  479. void
  480. list_iterator_next(list_iterator_t *li)
  481. {
  482. if (*li)
  483. *li = (*li)->next;
  484. }
  485. void
  486. list_iterator_prev(list_iterator_t *li)
  487. {
  488. if (*li)
  489. *li = (*li)->pred;
  490. }
  491. void *
  492. list_iterator_get_datum(list_iterator_t *li)
  493. {
  494. return *li ? (*li)->datum : NULL;
  495. }
  496. bool
  497. list_iterator_is_valid(list_iterator_t *li)
  498. {
  499. return (*li != NULL);
  500. }
  501. void
  502. list_reverse_iterator_init( list_t *l,
  503. list_reverse_iterator_t *li)
  504. {
  505. *li = l ? l->tail : NULL;
  506. }
  507. void
  508. list_reverse_iterator_delete(list_reverse_iterator_t *li)
  509. {
  510. *li = NULL;
  511. }
  512. void
  513. list_reverse_iterator_next(list_reverse_iterator_t *li)
  514. {
  515. if (*li)
  516. *li = (*li)->pred;
  517. }
  518. void
  519. list_reverse_iterator_prev(list_reverse_iterator_t *li)
  520. {
  521. if (*li)
  522. *li = (*li)->next;
  523. }
  524. void *
  525. list_reverse_iterator_get_datum(list_reverse_iterator_t *li)
  526. {
  527. return *li ? (*li)->datum : NULL;
  528. }
  529. bool
  530. list_reverse_iterator_is_valid(list_reverse_iterator_t *li)
  531. {
  532. return (li != NULL);
  533. }
  534. //======================================================================================================================================================150
  535. // OUTPUT AND UTILITIES
  536. //======================================================================================================================================================150
  537. /* */
  538. void *
  539. kmalloc(int size)
  540. {
  541. //printf("size: %d, current offset: %p\n",size,freeptr);
  542. void * r = (void *)freeptr;
  543. freeptr+=size;
  544. if(freeptr > malloc_size+(long)mem){
  545. printf("Memory Overflow\n");
  546. exit(1);
  547. }
  548. return r;
  549. }
  550. //transforms the current B+ Tree into a single, contiguous block of memory to be used on the GPU
  551. long
  552. transform_to_cuda( node * root,
  553. bool verbose)
  554. {
  555. struct timeval one,two;
  556. double time;
  557. gettimeofday (&one, NULL);
  558. long max_nodes = (long)(pow(order,log(size)/log(order/2.0)-1) + 1);
  559. malloc_size = size*sizeof(record) + max_nodes*sizeof(knode);
  560. mem = (char*)malloc(malloc_size);
  561. if(mem==NULL){
  562. printf("Initial malloc error\n");
  563. exit(1);
  564. }
  565. freeptr = (long)mem;
  566. krecords = (record * )kmalloc(size*sizeof(record));
  567. // printf("%d records\n", size);
  568. knodes = (knode *)kmalloc(max_nodes*sizeof(knode));
  569. // printf("%d knodes\n", max_nodes);
  570. queue = NULL;
  571. enqueue(root);
  572. node * n;
  573. knode * k;
  574. int i;
  575. long nodeindex = 0;
  576. long recordindex = 0;
  577. long queueindex = 0;
  578. knodes[0].location = nodeindex++;
  579. while( queue != NULL ) {
  580. n = dequeue();
  581. k = &knodes[queueindex];
  582. k->location = queueindex++;
  583. k->is_leaf = n->is_leaf;
  584. k->num_keys = n->num_keys+2;
  585. //start at 1 because 0 is set to INT_MIN
  586. k->keys[0]=INT_MIN;
  587. k->keys[k->num_keys-1]=INT_MAX;
  588. for(i=k->num_keys; i < order; i++)k->keys[i]=INT_MAX;
  589. if(!k->is_leaf){
  590. k->indices[0]=nodeindex++;
  591. // if(k->indices[0]>3953){
  592. // printf("ERROR: %d\n", k->indices[0]);
  593. // }
  594. for(i=1;i<k->num_keys-1;i++){
  595. k->keys[i] = n->keys[i-1];
  596. enqueue((node * )n->pointers[i-1]);
  597. k->indices[i] = nodeindex++;
  598. // if(k->indices[i]>3953){
  599. // printf("ERROR 1: %d\n", k->indices[i]);
  600. // }
  601. //knodes[nodeindex].location = nodeindex++;
  602. }
  603. //for final point of n
  604. enqueue((node * )n->pointers[i-1]);
  605. }
  606. else{
  607. k->indices[0]=0;
  608. for(i=1;i<k->num_keys-1;i++){
  609. k->keys[i] = n->keys[i-1];
  610. krecords[recordindex].value=((record *)n->pointers[i-1])->value;
  611. k->indices[i] = recordindex++;
  612. // if(k->indices[i]>3953){
  613. // printf("ERROR 2: %d\n", k->indices[i]);
  614. // }
  615. }
  616. }
  617. k->indices[k->num_keys-1]=queueindex;
  618. // if(k->indices[k->num_keys-1]>3953){
  619. // printf("ERROR 3: %d\n", k->indices[k->num_keys-1]);
  620. // }
  621. if(verbose){
  622. printf("Successfully created knode with index %d\n", k->location);
  623. printf("Is Leaf: %d, Num Keys: %d\n", k->is_leaf, k->num_keys);
  624. printf("Pointers: ");
  625. for(i=0;i<k->num_keys;i++)
  626. printf("%d | ", k->indices[i]);
  627. printf("\nKeys: ");
  628. for(i=0;i<k->num_keys;i++)
  629. printf("%d | ", k->keys[i]);
  630. printf("\n\n");
  631. }
  632. }
  633. long mem_used = size*sizeof(record)+(nodeindex)*sizeof(knode);
  634. if(verbose){
  635. for(i = 0; i < size; i++)
  636. printf("%d ", krecords[i].value);
  637. printf("\nNumber of records = %d, sizeof(record)=%d, total=%d\n",size,sizeof(record),size*sizeof(record));
  638. printf("Number of knodes = %d, sizeof(knode)=%d, total=%d\n",nodeindex,sizeof(knode),(nodeindex)*sizeof(knode));
  639. printf("\nDone Transformation. Mem used: %d\n", mem_used);
  640. }
  641. gettimeofday (&two, NULL);
  642. double oneD = one.tv_sec + (double)one.tv_usec * .000001;
  643. double twoD = two.tv_sec + (double)two.tv_usec * .000001;
  644. time = twoD-oneD;
  645. printf("Tree transformation took %f\n", time);
  646. return mem_used;
  647. }
  648. /* */
  649. list_t *
  650. findRange( node * root,
  651. int start,
  652. int end)
  653. {
  654. int i;
  655. node * c = find_leaf( root, start, false );
  656. if (c == NULL) return NULL;
  657. list_t * retList = (list_t *)malloc(sizeof(list_t));
  658. list_init(retList,NULL,NULL);
  659. int counter = 0;
  660. bool cont = true;
  661. while(cont && c!=0){
  662. cont = false;
  663. for(i = 0;i < c->num_keys;i++){
  664. if(c->keys[i] >= start && c->keys[i] <= end){
  665. //list_insert_tail(retList,(record *)c->pointers[i]);
  666. counter++;
  667. cont = true;
  668. }else{
  669. cont = false;
  670. break;
  671. }
  672. }
  673. c = (node *)c->pointers[order-1];
  674. }
  675. return retList;
  676. }
  677. /* First message to the user. */
  678. void
  679. usage_1( void )
  680. {
  681. printf("B+ Tree of Order %d.\n", order);
  682. printf("\tAmittai Aviram -- amittai.aviram@yale.edu Version %s\n", Version);
  683. printf("\tfollowing Silberschatz, Korth, Sidarshan, Database Concepts, 5th ed.\n\n");
  684. printf("To build a B+ tree of a different order, start again and enter the order\n");
  685. printf("as an integer argument: bpt <order>. ");
  686. printf("3 <= order <=20\n");
  687. printf("To start with input from a file of newline-delimited integers, start again and enter\n");
  688. printf("the order followed by the filename: bpt <order> <inputfile>.\n");
  689. }
  690. /* Second message to the user. */
  691. void
  692. usage_2( void )
  693. {
  694. printf("Enter any of the following commands after the prompt > :\n");
  695. printf("\ti <k> -- Insert <k> (an integer) as both key and value).\n");
  696. printf("\tf <k> -- Find the value under key <k>.\n");
  697. printf("\tp <k> -- Print the path from the root to key k and its associated value.\n");
  698. printf("\td <k> -- Delete key <k> and its associated value.\n");
  699. printf("\tx -- Destroy the whole tree. Start again with an empty tree of the same order.\n");
  700. printf("\tt -- Print the B+ tree.\n");
  701. printf("\tl -- Print the keys of the leaves (bottom row of the tree).\n");
  702. printf("\tv -- Toggle output of pointer addresses (\"verbose\") in tree and leaves.\n");
  703. printf("\tq -- Quit. (Or use Ctl-D.)\n");
  704. printf("\t? -- Print this help message.\n");
  705. }
  706. /* Helper function for printing the tree out. See print_tree. */
  707. void
  708. enqueue( node* new_node )
  709. {
  710. node * c;
  711. if (queue == NULL) {
  712. queue = new_node;
  713. queue->next = NULL;
  714. }
  715. else {
  716. c = queue;
  717. while(c->next != NULL) {
  718. c = c->next;
  719. }
  720. c->next = new_node;
  721. new_node->next = NULL;
  722. }
  723. }
  724. /* Helper function for printing the tree out. See print_tree. */
  725. node *
  726. dequeue( void )
  727. {
  728. node * n = queue;
  729. queue = queue->next;
  730. n->next = NULL;
  731. return n;
  732. }
  733. /* Prints the bottom row of keys of the tree (with their respective pointers, if the verbose_output flag is set. */
  734. void
  735. print_leaves( node* root )
  736. {
  737. int i;
  738. node * c = root;
  739. if (root == NULL) {
  740. printf("Empty tree.\n");
  741. return;
  742. }
  743. while (!c->is_leaf)
  744. c = (node *) c->pointers[0];
  745. while (true) {
  746. for (i = 0; i < c->num_keys; i++) {
  747. if (verbose_output)
  748. //printf("%x ", (unsigned int)c->pointers[i]);
  749. printf("%d ", c->keys[i]);
  750. }
  751. if (verbose_output)
  752. //printf("%x ", (unsigned int)c->pointers[order - 1]);
  753. if (c->pointers[order - 1] != NULL) {
  754. printf(" | ");
  755. c = (node *) c->pointers[order - 1];
  756. }
  757. else
  758. break;
  759. }
  760. printf("\n");
  761. }
  762. /* Utility function to give the height of the tree, which length in number of edges of the path from the root to any leaf. */
  763. int
  764. height( node* root )
  765. {
  766. int h = 0;
  767. node * c = root;
  768. while (!c->is_leaf) {
  769. c = (node *) c->pointers[0];
  770. h++;
  771. }
  772. return h;
  773. }
  774. /* Utility function to give the length in edges of the path from any node to the root. */
  775. int
  776. path_to_root( node* root, node* child )
  777. {
  778. int length = 0;
  779. node * c = child;
  780. while (c != root) {
  781. c = c->parent;
  782. length++;
  783. }
  784. return length;
  785. }
  786. /* Prints the B+ tree in the command line in level (rank) order, with the keys in each node and the '|' symbol to separate nodes. With the verbose_output flag set. the values of the pointers corresponding to the keys also appear next to their respective keys, in hexadecimal notation. */
  787. void
  788. print_tree( node* root )
  789. {
  790. node * n = NULL;
  791. int i = 0;
  792. int rank = 0;
  793. int new_rank = 0;
  794. if (root == NULL) {
  795. printf("Empty tree.\n");
  796. return;
  797. }
  798. queue = NULL;
  799. enqueue(root);
  800. while( queue != NULL ) {
  801. n = dequeue();
  802. if (n->parent != NULL && n == n->parent->pointers[0]) {
  803. new_rank = path_to_root( root, n );
  804. if (new_rank != rank) {
  805. rank = new_rank;
  806. printf("\n");
  807. }
  808. }
  809. if (verbose_output)
  810. printf("(%x)", n);
  811. for (i = 0; i < n->num_keys; i++) {
  812. if (verbose_output)
  813. printf("%x ", n->pointers[i]);
  814. printf("%d ", n->keys[i]);
  815. }
  816. if (!n->is_leaf)
  817. for (i = 0; i <= n->num_keys; i++)
  818. enqueue((node *) n->pointers[i]);
  819. if (verbose_output) {
  820. if (n->is_leaf)
  821. printf("%x ", n->pointers[order - 1]);
  822. else
  823. printf("%x ", n->pointers[n->num_keys]);
  824. }
  825. printf("| ");
  826. }
  827. printf("\n");
  828. }
  829. /* Traces the path from the root to a leaf, searching by key. Displays information about the path if the verbose flag is set. Returns the leaf containing the given key. */
  830. node *
  831. find_leaf( node* root, int key, bool verbose )
  832. {
  833. int i = 0;
  834. node * c = root;
  835. if (c == NULL) {
  836. if (verbose)
  837. printf("Empty tree.\n");
  838. return c;
  839. }
  840. while (!c->is_leaf) {
  841. if (verbose) {
  842. printf("[");
  843. for (i = 0; i < c->num_keys - 1; i++)
  844. printf("%d ", c->keys[i]);
  845. printf("%d] ", c->keys[i]);
  846. }
  847. i = 0;
  848. while (i < c->num_keys) {
  849. if (key >= c->keys[i])
  850. i++;
  851. else
  852. break;
  853. }
  854. if (verbose)
  855. printf("%d ->\n", i);
  856. c = (node *)c->pointers[i];
  857. }
  858. if (verbose) {
  859. printf("Leaf [");
  860. for (i = 0; i < c->num_keys - 1; i++)
  861. printf("%d ", c->keys[i]);
  862. printf("%d] ->\n", c->keys[i]);
  863. }
  864. return c;
  865. }
  866. /* Finds and returns the record to which a key refers. */
  867. record *
  868. find( node* root, int key, bool verbose )
  869. {
  870. int i = 0;
  871. node * c = find_leaf( root, key, verbose );
  872. if (c == NULL)
  873. return NULL;
  874. for (i = 0; i < c->num_keys; i++)
  875. if (c->keys[i] == key)
  876. break;
  877. if (i == c->num_keys)
  878. return NULL;
  879. else
  880. return (record *)c->pointers[i];
  881. }
  882. /* Finds the appropriate place to split a node that is too big into two. */
  883. int
  884. cut( int length )
  885. {
  886. if (length % 2 == 0)
  887. return length/2;
  888. else
  889. return length/2 + 1;
  890. }
  891. //======================================================================================================================================================150
  892. // INSERTION
  893. //======================================================================================================================================================150
  894. /* Creates a new record to hold the value to which a key refers. */
  895. record *
  896. make_record(int value)
  897. {
  898. record * new_record = (record *)malloc(sizeof(record));
  899. if (new_record == NULL) {
  900. perror("Record creation.");
  901. exit(EXIT_FAILURE);
  902. }
  903. else {
  904. new_record->value = value;
  905. }
  906. return new_record;
  907. }
  908. /* Creates a new general node, which can be adapted to serve as either a leaf or an internal node. */
  909. node *
  910. make_node( void )
  911. {
  912. node * new_node;
  913. new_node = (node *) malloc(sizeof(node));
  914. if (new_node == NULL) {
  915. perror("Node creation.");
  916. exit(EXIT_FAILURE);
  917. }
  918. new_node->keys = (int *) malloc( (order - 1) * sizeof(int) );
  919. if (new_node->keys == NULL) {
  920. perror("New node keys array.");
  921. exit(EXIT_FAILURE);
  922. }
  923. new_node->pointers = (void **) malloc( order * sizeof(void *) );
  924. if (new_node->pointers == NULL) {
  925. perror("New node pointers array.");
  926. exit(EXIT_FAILURE);
  927. }
  928. new_node->is_leaf = false;
  929. new_node->num_keys = 0;
  930. new_node->parent = NULL;
  931. new_node->next = NULL;
  932. return new_node;
  933. }
  934. /* Creates a new leaf by creating a node and then adapting it appropriately. */
  935. node *
  936. make_leaf( void )
  937. {
  938. node* leaf = make_node();
  939. leaf->is_leaf = true;
  940. return leaf;
  941. }
  942. /* Helper function used in insert_into_parent to find the index of the parent's pointer to the node to the left of the key to be inserted. */
  943. int
  944. get_left_index(node* parent, node* left)
  945. {
  946. int left_index = 0;
  947. while (left_index <= parent->num_keys &&
  948. parent->pointers[left_index] != left)
  949. left_index++;
  950. return left_index;
  951. }
  952. /* Inserts a new pointer to a record and its corresponding key into a leaf. Returns the altered leaf. */
  953. node *
  954. insert_into_leaf( node* leaf, int key, record* pointer )
  955. {
  956. int i, insertion_point;
  957. insertion_point = 0;
  958. while (insertion_point < leaf->num_keys && leaf->keys[insertion_point] < key)
  959. insertion_point++;
  960. for (i = leaf->num_keys; i > insertion_point; i--) {
  961. leaf->keys[i] = leaf->keys[i - 1];
  962. leaf->pointers[i] = leaf->pointers[i - 1];
  963. }
  964. leaf->keys[insertion_point] = key;
  965. leaf->pointers[insertion_point] = pointer;
  966. leaf->num_keys++;
  967. return leaf;
  968. }
  969. /* Inserts a new key and pointer to a new record into a leaf so as to exceed the tree's order, causing the leaf to be split in half. */
  970. node *
  971. insert_into_leaf_after_splitting( node* root,
  972. node* leaf,
  973. int key,
  974. record* pointer)
  975. {
  976. node * new_leaf;
  977. int * temp_keys;
  978. void ** temp_pointers;
  979. int insertion_index, split, new_key, i, j;
  980. new_leaf = make_leaf();
  981. temp_keys = (int *) malloc( order * sizeof(int) );
  982. if (temp_keys == NULL) {
  983. perror("Temporary keys array.");
  984. exit(EXIT_FAILURE);
  985. }
  986. temp_pointers = (void **) malloc( order * sizeof(void *) );
  987. if (temp_pointers == NULL) {
  988. perror("Temporary pointers array.");
  989. exit(EXIT_FAILURE);
  990. }
  991. insertion_index = 0;
  992. while (leaf->keys[insertion_index] < key && insertion_index < order - 1)
  993. insertion_index++;
  994. for (i = 0, j = 0; i < leaf->num_keys; i++, j++) {
  995. if (j == insertion_index) j++;
  996. temp_keys[j] = leaf->keys[i];
  997. temp_pointers[j] = leaf->pointers[i];
  998. }
  999. temp_keys[insertion_index] = key;
  1000. temp_pointers[insertion_index] = pointer;
  1001. leaf->num_keys = 0;
  1002. split = cut(order - 1);
  1003. for (i = 0; i < split; i++) {
  1004. leaf->pointers[i] = temp_pointers[i];
  1005. leaf->keys[i] = temp_keys[i];
  1006. leaf->num_keys++;
  1007. }
  1008. for (i = split, j = 0; i < order; i++, j++) {
  1009. new_leaf->pointers[j] = temp_pointers[i];
  1010. new_leaf->keys[j] = temp_keys[i];
  1011. new_leaf->num_keys++;
  1012. }
  1013. free(temp_pointers);
  1014. free(temp_keys);
  1015. new_leaf->pointers[order - 1] = leaf->pointers[order - 1];
  1016. leaf->pointers[order - 1] = new_leaf;
  1017. for (i = leaf->num_keys; i < order - 1; i++)
  1018. leaf->pointers[i] = NULL;
  1019. for (i = new_leaf->num_keys; i < order - 1; i++)
  1020. new_leaf->pointers[i] = NULL;
  1021. new_leaf->parent = leaf->parent;
  1022. new_key = new_leaf->keys[0];
  1023. return insert_into_parent(root, leaf, new_key, new_leaf);
  1024. }
  1025. /* Inserts a new key and pointer to a node into a node into which these can fit without violating the B+ tree properties. */
  1026. node *
  1027. insert_into_node( node* root,
  1028. node* n,
  1029. int left_index,
  1030. int key,
  1031. node* right)
  1032. {
  1033. int i;
  1034. for (i = n->num_keys; i > left_index; i--) {
  1035. n->pointers[i + 1] = n->pointers[i];
  1036. n->keys[i] = n->keys[i - 1];
  1037. }
  1038. n->pointers[left_index + 1] = right;
  1039. n->keys[left_index] = key;
  1040. n->num_keys++;
  1041. return root;
  1042. }
  1043. /* Inserts a new key and pointer to a node into a node, causing the node's size to exceed the order, and causing the node to split into two. */
  1044. node *
  1045. insert_into_node_after_splitting( node* root,
  1046. node* old_node,
  1047. int left_index,
  1048. int key,
  1049. node * right)
  1050. {
  1051. int i, j, split, k_prime;
  1052. node * new_node, * child;
  1053. int * temp_keys;
  1054. node ** temp_pointers;
  1055. /* First create a temporary set of keys and pointers
  1056. * to hold everything in order, including
  1057. * the new key and pointer, inserted in their
  1058. * correct places.
  1059. * Then create a new node and copy half of the
  1060. * keys and pointers to the old node and
  1061. * the other half to the new.
  1062. */
  1063. temp_pointers = (node **) malloc( (order + 1) * sizeof(node *) );
  1064. if (temp_pointers == NULL) {
  1065. perror("Temporary pointers array for splitting nodes.");
  1066. exit(EXIT_FAILURE);
  1067. }
  1068. temp_keys = (int *) malloc( order * sizeof(int) );
  1069. if (temp_keys == NULL) {
  1070. perror("Temporary keys array for splitting nodes.");
  1071. exit(EXIT_FAILURE);
  1072. }
  1073. for (i = 0, j = 0; i < old_node->num_keys + 1; i++, j++) {
  1074. if (j == left_index + 1) j++;
  1075. temp_pointers[j] = (node *) old_node->pointers[i];
  1076. }
  1077. for (i = 0, j = 0; i < old_node->num_keys; i++, j++) {
  1078. if (j == left_index) j++;
  1079. temp_keys[j] = old_node->keys[i];
  1080. }
  1081. temp_pointers[left_index + 1] = right;
  1082. temp_keys[left_index] = key;
  1083. /* Create the new node and copy
  1084. * half the keys and pointers to the
  1085. * old and half to the new.
  1086. */
  1087. split = cut(order);
  1088. new_node = make_node();
  1089. old_node->num_keys = 0;
  1090. for (i = 0; i < split - 1; i++) {
  1091. old_node->pointers[i] = temp_pointers[i];
  1092. old_node->keys[i] = temp_keys[i];
  1093. old_node->num_keys++;
  1094. }
  1095. old_node->pointers[i] = temp_pointers[i];
  1096. k_prime = temp_keys[split - 1];
  1097. for (++i, j = 0; i < order; i++, j++) {
  1098. new_node->pointers[j] = temp_pointers[i];
  1099. new_node->keys[j] = temp_keys[i];
  1100. new_node->num_keys++;
  1101. }
  1102. new_node->pointers[j] = temp_pointers[i];
  1103. free(temp_pointers);
  1104. free(temp_keys);
  1105. new_node->parent = old_node->parent;
  1106. for (i = 0; i <= new_node->num_keys; i++) {
  1107. child = (node *) new_node->pointers[i];
  1108. child->parent = new_node;
  1109. }
  1110. /* Insert a new key into the parent of the two
  1111. * nodes resulting from the split, with
  1112. * the old node to the left and the new to the right.
  1113. */
  1114. return insert_into_parent(root, old_node, k_prime, new_node);
  1115. }
  1116. /* Inserts a new node (leaf or internal node) into the B+ tree. Returns the root of the tree after insertion. */
  1117. node *
  1118. insert_into_parent( node* root,
  1119. node* left,
  1120. int key,
  1121. node* right)
  1122. {
  1123. int left_index;
  1124. node * parent;
  1125. parent = left->parent;
  1126. /* Case: new root. */
  1127. if (parent == NULL)
  1128. return insert_into_new_root(left, key, right);
  1129. /* Case: leaf or node. (Remainder of
  1130. * function body.)
  1131. */
  1132. /* Find the parent's pointer to the left
  1133. * node.
  1134. */
  1135. left_index = get_left_index(parent, left);
  1136. /* Simple case: the new key fits into the node.
  1137. */
  1138. if (parent->num_keys < order - 1)
  1139. return insert_into_node(root, parent, left_index, key, right);
  1140. /* Harder case: split a node in order
  1141. * to preserve the B+ tree properties.
  1142. */
  1143. return insert_into_node_after_splitting(root, parent, left_index, key, right);
  1144. }
  1145. /* Creates a new root for two subtrees and inserts the appropriate key into the new root. */
  1146. node *
  1147. insert_into_new_root( node* left,
  1148. int key,
  1149. node* right)
  1150. {
  1151. node * root = make_node();
  1152. root->keys[0] = key;
  1153. root->pointers[0] = left;
  1154. root->pointers[1] = right;
  1155. root->num_keys++;
  1156. root->parent = NULL;
  1157. left->parent = root;
  1158. right->parent = root;
  1159. return root;
  1160. }
  1161. /* First insertion: start a new tree. */
  1162. node *
  1163. start_new_tree( int key,
  1164. record* pointer)
  1165. {
  1166. node * root = make_leaf();
  1167. root->keys[0] = key;
  1168. root->pointers[0] = pointer;
  1169. root->pointers[order - 1] = NULL;
  1170. root->parent = NULL;
  1171. root->num_keys++;
  1172. return root;
  1173. }
  1174. /* Master insertion function. Inserts a key and an associated value into the B+ tree, causing the tree to be adjusted however necessary to maintain the B+ tree properties. */
  1175. node *
  1176. insert( node* root,
  1177. int key,
  1178. int value )
  1179. {
  1180. record* pointer;
  1181. node* leaf;
  1182. /* The current implementation ignores duplicates. */
  1183. if (find(root, key, false) != NULL)
  1184. return root;
  1185. /* Create a new record for the value. */
  1186. pointer = make_record(value);
  1187. /* Case: the tree does not exist yet. Start a new tree. */
  1188. if (root == NULL)
  1189. return start_new_tree(key, pointer);
  1190. /* Case: the tree already exists. (Rest of function body.) */
  1191. leaf = find_leaf(root, key, false);
  1192. /* Case: leaf has room for key and pointer. */
  1193. if (leaf->num_keys < order - 1) {
  1194. leaf = insert_into_leaf(leaf, key, pointer);
  1195. return root;
  1196. }
  1197. /* Case: leaf must be split. */
  1198. return insert_into_leaf_after_splitting(root, leaf, key, pointer);
  1199. }
  1200. //======================================================================================================================================================150
  1201. // DELETION
  1202. //======================================================================================================================================================150
  1203. /* Utility function for deletion. Retrieves the index of a node's nearest neighbor (sibling) to the left if one exists. If not (the node is the leftmost child), returns -1 to signify this special case. */
  1204. int
  1205. get_neighbor_index( node* n )
  1206. {
  1207. int i;
  1208. /* Return the index of the key to the left
  1209. * of the pointer in the parent pointing
  1210. * to n.
  1211. * If n is the leftmost child, this means
  1212. * return -1.
  1213. */
  1214. for (i = 0; i <= n->parent->num_keys; i++)
  1215. if (n->parent->pointers[i] == n)
  1216. return i - 1;
  1217. // Error state.
  1218. printf("Search for nonexistent pointer to node in parent.\n");
  1219. //printf("Node: %#x\n", (unsigned int)n);
  1220. exit(EXIT_FAILURE);
  1221. }
  1222. /* */
  1223. node*
  1224. remove_entry_from_node( node* n,
  1225. int key,
  1226. node * pointer)
  1227. {
  1228. int i, num_pointers;
  1229. // Remove the key and shift other keys accordingly.
  1230. i = 0;
  1231. while (n->keys[i] != key)
  1232. i++;
  1233. for (++i; i < n->num_keys; i++)
  1234. n->keys[i - 1] = n->keys[i];
  1235. // Remove the pointer and shift other pointers accordingly.
  1236. // First determine number of pointers.
  1237. num_pointers = n->is_leaf ? n->num_keys : n->num_keys + 1;
  1238. i = 0;
  1239. while (n->pointers[i] != pointer)
  1240. i++;
  1241. for (++i; i < num_pointers; i++)
  1242. n->pointers[i - 1] = n->pointers[i];
  1243. // One key fewer.
  1244. n->num_keys--;
  1245. // Set the other pointers to NULL for tidiness.
  1246. // A leaf uses the last pointer to point to the next leaf.
  1247. if (n->is_leaf)
  1248. for (i = n->num_keys; i < order - 1; i++)
  1249. n->pointers[i] = NULL;
  1250. else
  1251. for (i = n->num_keys + 1; i < order; i++)
  1252. n->pointers[i] = NULL;
  1253. return n;
  1254. }
  1255. /* */
  1256. node*
  1257. adjust_root(node* root)
  1258. {
  1259. node * new_root;
  1260. /* Case: nonempty root.
  1261. * Key and pointer have already been deleted,
  1262. * so nothing to be done.
  1263. */
  1264. if (root->num_keys > 0)
  1265. return root;
  1266. /* Case: empty root.
  1267. */
  1268. // If it has a child, promote
  1269. // the first (only) child
  1270. // as the new root.
  1271. if (!root->is_leaf) {
  1272. new_root = (node *) root->pointers[0];
  1273. new_root->parent = NULL;
  1274. }
  1275. // If it is a leaf (has no children),
  1276. // then the whole tree is empty.
  1277. else
  1278. new_root = NULL;
  1279. free(root->keys);
  1280. free(root->pointers);
  1281. free(root);
  1282. return new_root;
  1283. }
  1284. /* Coalesces a node that has become too small after deletion with a neighboring node that can accept the additional entries without exceeding the maximum. */
  1285. node*
  1286. coalesce_nodes( node* root,
  1287. node* n,
  1288. node* neighbor,
  1289. int neighbor_index,
  1290. int k_prime)
  1291. {
  1292. int i, j, neighbor_insertion_index, n_start, n_end, new_k_prime;
  1293. node * tmp;
  1294. bool split;
  1295. /* Swap neighbor with node if node is on the
  1296. * extreme left and neighbor is to its right.
  1297. */
  1298. if (neighbor_index == -1) {
  1299. tmp = n;
  1300. n = neighbor;
  1301. neighbor = tmp;
  1302. }
  1303. /* Starting point in the neighbor for copying
  1304. * keys and pointers from n.
  1305. * Recall that n and neighbor have swapped places
  1306. * in the special case of n being a leftmost child.
  1307. */
  1308. neighbor_insertion_index = neighbor->num_keys;
  1309. /*
  1310. * Nonleaf nodes may sometimes need to remain split,
  1311. * if the insertion of k_prime would cause the resulting
  1312. * single coalesced node to exceed the limit order - 1.
  1313. * The variable split is always false for leaf nodes
  1314. * and only sometimes set to true for nonleaf nodes.
  1315. */
  1316. split = false;
  1317. /* Case: nonleaf node.
  1318. * Append k_prime and the following pointer.
  1319. * If there is room in the neighbor, append
  1320. * all pointers and keys from the neighbor.
  1321. * Otherwise, append only cut(order) - 2 keys and
  1322. * cut(order) - 1 pointers.
  1323. */
  1324. if (!n->is_leaf) {
  1325. /* Append k_prime.
  1326. */
  1327. neighbor->keys[neighbor_insertion_index] = k_prime;
  1328. neighbor->num_keys++;
  1329. /* Case (default): there is room for all of n's keys and pointers
  1330. * in the neighbor after appending k_prime.
  1331. */
  1332. n_end = n->num_keys;
  1333. /* Case (special): k cannot fit with all the other keys and pointers
  1334. * into one coalesced node.
  1335. */
  1336. n_start = 0; // Only used in this special case.
  1337. if (n->num_keys + neighbor->num_keys >= order) {
  1338. split = true;
  1339. n_end = cut(order) - 2;
  1340. }
  1341. for (i = neighbor_insertion_index + 1, j = 0; j < n_end; i++, j++) {
  1342. neighbor->keys[i] = n->keys[j];
  1343. neighbor->pointers[i] = n->pointers[j];
  1344. neighbor->num_keys++;
  1345. n->num_keys--;
  1346. n_start++;
  1347. }
  1348. /* The number of pointers is always
  1349. * one more than the number of keys.
  1350. */
  1351. neighbor->pointers[i] = n->pointers[j];
  1352. /* If the nodes are still split, remove the first key from
  1353. * n.
  1354. */
  1355. if (split) {
  1356. new_k_prime = n->keys[n_start];
  1357. for (i = 0, j = n_start + 1; i < n->num_keys; i++, j++) {
  1358. n->keys[i] = n->keys[j];
  1359. n->pointers[i] = n->pointers[j];
  1360. }
  1361. n->pointers[i] = n->pointers[j];
  1362. n->num_keys--;
  1363. }
  1364. /* All children must now point up to the same parent.
  1365. */
  1366. for (i = 0; i < neighbor->num_keys + 1; i++) {
  1367. tmp = (node *)neighbor->pointers[i];
  1368. tmp->parent = neighbor;
  1369. }
  1370. }
  1371. /* In a leaf, append the keys and pointers of
  1372. * n to the neighbor.
  1373. * Set the neighbor's last pointer to point to
  1374. * what had been n's right neighbor.
  1375. */
  1376. else {
  1377. for (i = neighbor_insertion_index, j = 0; j < n->num_keys; i++, j++) {
  1378. neighbor->keys[i] = n->keys[j];
  1379. neighbor->pointers[i] = n->pointers[j];
  1380. neighbor->num_keys++;
  1381. }
  1382. neighbor->pointers[order - 1] = n->pointers[order - 1];
  1383. }
  1384. if (!split) {
  1385. root = delete_entry(root, n->parent, k_prime, n);
  1386. free(n->keys);
  1387. free(n->pointers);
  1388. free(n);
  1389. }
  1390. else
  1391. for (i = 0; i < n->parent->num_keys; i++)
  1392. if (n->parent->pointers[i + 1] == n) {
  1393. n->parent->keys[i] = new_k_prime;
  1394. break;
  1395. }
  1396. return root;
  1397. }
  1398. /* Redistributes entries between two nodes when one has become too small after deletion but its neighbor is too big to append the small node's entries without exceeding the maximum */
  1399. node*
  1400. redistribute_nodes( node* root,
  1401. node* n,
  1402. node* neighbor,
  1403. int neighbor_index,
  1404. int k_prime_index,
  1405. int k_prime)
  1406. {
  1407. int i;
  1408. node * tmp;
  1409. /* Case: n has a neighbor to the left.
  1410. * Pull the neighbor's last key-pointer pair over
  1411. * from the neighbor's right end to n's left end.
  1412. */
  1413. if (neighbor_index != -1) {
  1414. if (!n->is_leaf)
  1415. n->pointers[n->num_keys + 1] = n->pointers[n->num_keys];
  1416. for (i = n->num_keys; i > 0; i--) {
  1417. n->keys[i] = n->keys[i - 1];
  1418. n->pointers[i] = n->pointers[i - 1];
  1419. }
  1420. if (!n->is_leaf) {
  1421. n->pointers[0] = neighbor->pointers[neighbor->num_keys];
  1422. tmp = (node *)n->pointers[0];
  1423. tmp->parent = n;
  1424. neighbor->pointers[neighbor->num_keys] = NULL;
  1425. n->keys[0] = k_prime;
  1426. n->parent->keys[k_prime_index] = neighbor->keys[neighbor->num_keys - 1];
  1427. }
  1428. else {
  1429. n->pointers[0] = neighbor->pointers[neighbor->num_keys - 1];
  1430. neighbor->pointers[neighbor->num_keys - 1] = NULL;
  1431. n->keys[0] = neighbor->keys[neighbor->num_keys - 1];
  1432. n->parent->keys[k_prime_index] = n->keys[0];
  1433. }
  1434. }
  1435. /* Case: n is the leftmost child.
  1436. * Take a key-pointer pair from the neighbor to the right.
  1437. * Move the neighbor's leftmost key-pointer pair
  1438. * to n's rightmost position.
  1439. */
  1440. else {
  1441. if (n->is_leaf) {
  1442. n->keys[n->num_keys] = neighbor->keys[0];
  1443. n->pointers[n->num_keys] = neighbor->pointers[0];
  1444. n->parent->keys[k_prime_index] = neighbor->keys[1];
  1445. }
  1446. else {
  1447. n->keys[n->num_keys] = k_prime;
  1448. n->pointers[n->num_keys + 1] = neighbor->pointers[0];
  1449. tmp = (node *)n->pointers[n->num_keys + 1];
  1450. tmp->parent = n;
  1451. n->parent->keys[k_prime_index] = neighbor->keys[0];
  1452. }
  1453. for (i = 0; i < neighbor->num_keys; i++) {
  1454. neighbor->keys[i] = neighbor->keys[i + 1];
  1455. neighbor->pointers[i] = neighbor->pointers[i + 1];
  1456. }
  1457. if (!n->is_leaf)
  1458. neighbor->pointers[i] = neighbor->pointers[i + 1];
  1459. }
  1460. /* n now has one more key and one more pointer;
  1461. * the neighbor has one fewer of each.
  1462. */
  1463. n->num_keys++;
  1464. neighbor->num_keys--;
  1465. return root;
  1466. }
  1467. /* Deletes an entry from the B+ tree. Removes the record and its key and pointer from the leaf, and then makes all appropriate changes to preserve the B+ tree properties. */
  1468. node*
  1469. delete_entry( node* root,
  1470. node* n,
  1471. int key,
  1472. void* pointer )
  1473. {
  1474. int min_keys;
  1475. node * neighbor;
  1476. int neighbor_index;
  1477. int k_prime_index, k_prime;
  1478. int capacity;
  1479. // Remove key and pointer from node.
  1480. n = remove_entry_from_node(n, key, (node *) pointer);
  1481. /* Case: deletion from the root.
  1482. */
  1483. if (n == root)
  1484. return adjust_root(root);
  1485. /* Case: deletion from a node below the root.
  1486. * (Rest of function body.)
  1487. */
  1488. /* Determine minimum allowable size of node,
  1489. * to be preserved after deletion.
  1490. */
  1491. min_keys = n->is_leaf ? cut(order - 1) : cut(order) - 1;
  1492. /* Case: node stays at or above minimum.
  1493. * (The simple case.)
  1494. */
  1495. if (n->num_keys >= min_keys)
  1496. return root;
  1497. /* Case: node falls below minimum.
  1498. * Either coalescence or redistribution
  1499. * is needed.
  1500. */
  1501. /* Find the appropriate neighbor node with which
  1502. * to coalesce.
  1503. * Also find the key (k_prime) in the parent
  1504. * between the pointer to node n and the pointer
  1505. * to the neighbor.
  1506. */
  1507. neighbor_index = get_neighbor_index( n );
  1508. k_prime_index = neighbor_index == -1 ? 0 : neighbor_index;
  1509. k_prime = n->parent->keys[k_prime_index];
  1510. neighbor = neighbor_index == -1 ? (node *) n->parent->pointers[1] :
  1511. (node *)n->parent->pointers[neighbor_index];
  1512. capacity = n->is_leaf ? order : order - 1;
  1513. /* Coalescence. */
  1514. if (neighbor->num_keys + n->num_keys < capacity)
  1515. return coalesce_nodes(root, n, neighbor, neighbor_index, k_prime);
  1516. /* Redistribution. */
  1517. else
  1518. return redistribute_nodes(root, n, neighbor, neighbor_index, k_prime_index, k_prime);
  1519. }
  1520. /* Master deletion function. */
  1521. node*
  1522. deleteVal( node* root,
  1523. int key)
  1524. {
  1525. node * key_leaf;
  1526. record * key_record;
  1527. key_record = find(root, key, false);
  1528. key_leaf = find_leaf(root, key, false);
  1529. if (key_record != NULL && key_leaf != NULL) {
  1530. free(key_record);
  1531. root = delete_entry(root, key_leaf, key, key_record);
  1532. }
  1533. return root;
  1534. }
  1535. /* */
  1536. void
  1537. destroy_tree_nodes(node* root)
  1538. {
  1539. int i;
  1540. if (root->is_leaf)
  1541. for (i = 0; i < root->num_keys; i++)
  1542. free(root->pointers[i]);
  1543. else
  1544. for (i = 0; i < root->num_keys + 1; i++)
  1545. destroy_tree_nodes((node *) root->pointers[i]);
  1546. free(root->pointers);
  1547. free(root->keys);
  1548. free(root);
  1549. }
  1550. /* */
  1551. node*
  1552. destroy_tree(node* root)
  1553. {
  1554. destroy_tree_nodes(root);
  1555. return NULL;
  1556. }
  1557. //======================================================================================================================================================150
  1558. // END
  1559. //======================================================================================================================================================150
  1560. //========================================================================================================================================================================================================200
  1561. // MAIN FUNCTION
  1562. //========================================================================================================================================================================================================200
  1563. int
  1564. main( int argc,
  1565. char** argv )
  1566. {
  1567. printf("WG size of kernel 1 = %d WG size of kernel 2 = %d \n", DEFAULT_ORDER, DEFAULT_ORDER_2);
  1568. // ------------------------------------------------------------60
  1569. // figure out and display whether 32-bit or 64-bit architecture
  1570. // ------------------------------------------------------------60
  1571. // if(sizeof(int *)==8){
  1572. // printf("64 bit machine\n");
  1573. // }
  1574. // else if(sizeof(int *)==4){
  1575. // printf("32 bit machine\n");
  1576. // }
  1577. // ------------------------------------------------------------60
  1578. // read inputs
  1579. // ------------------------------------------------------------60
  1580. // assing default values
  1581. int cur_arg;
  1582. int arch_arg;
  1583. arch_arg = 0;
  1584. int cores_arg;
  1585. cores_arg = 1;
  1586. char *input_file = NULL;
  1587. char *command_file = NULL;
  1588. char *output="output.txt";
  1589. FILE * pFile;
  1590. // go through arguments
  1591. for(cur_arg=1; cur_arg<argc; cur_arg++){
  1592. // check if -file
  1593. if(strcmp(argv[cur_arg], "file")==0){
  1594. // check if value provided
  1595. if(argc>=cur_arg+1){
  1596. input_file = argv[cur_arg+1];
  1597. cur_arg = cur_arg+1;
  1598. // value is not a number
  1599. }
  1600. // value not provided
  1601. else{
  1602. printf("ERROR: Missing value to -file parameter\n");
  1603. return -1;
  1604. }
  1605. }
  1606. else if(strcmp(argv[cur_arg], "command")==0){
  1607. // check if value provided
  1608. if(argc>=cur_arg+1){
  1609. command_file = argv[cur_arg+1];
  1610. cur_arg = cur_arg+1;
  1611. // value is not a number
  1612. }
  1613. // value not provided
  1614. else{
  1615. printf("ERROR: Missing value to command parameter\n");
  1616. return -1;
  1617. }
  1618. }
  1619. }
  1620. // Print configuration
  1621. if((input_file==NULL)||(command_file==NULL))
  1622. printf("Usage: ./b+tree file input_file command command_list\n");
  1623. // For debug
  1624. printf("Input File: %s \n", input_file);
  1625. printf("Command File: %s \n", command_file);
  1626. FILE * commandFile;
  1627. long lSize;
  1628. char * commandBuffer;
  1629. size_t result;
  1630. commandFile = fopen ( command_file, "rb" );
  1631. if (commandFile==NULL) {fputs ("Command File error",stderr); exit (1);}
  1632. // obtain file size:
  1633. fseek (commandFile , 0 , SEEK_END);
  1634. lSize = ftell (commandFile);
  1635. rewind (commandFile);
  1636. // allocate memory to contain the whole file:
  1637. commandBuffer = (char*) malloc (sizeof(char)*lSize);
  1638. if (commandBuffer == NULL) {fputs ("Command Buffer memory error",stderr); exit (2);}
  1639. // copy the file into the buffer:
  1640. result = fread (commandBuffer,1,lSize,commandFile);
  1641. if (result != lSize) {fputs ("Command file reading error",stderr); exit (3);}
  1642. /* the whole file is now loaded in the memory buffer. */
  1643. // terminate
  1644. fclose (commandFile);
  1645. // For Debug
  1646. char *sPointer=commandBuffer;
  1647. printf("Command Buffer: \n");
  1648. printf("%s",commandBuffer);
  1649. //
  1650. pFile = fopen (output,"w+");
  1651. if (pFile==NULL)
  1652. fputs ("Fail to open %s !\n",output);
  1653. fprintf(pFile,"******starting******\n");
  1654. fclose(pFile);
  1655. // ------------------------------------------------------------60
  1656. // general variables
  1657. // ------------------------------------------------------------60
  1658. FILE *file_pointer;
  1659. node *root;
  1660. root = NULL;
  1661. record *r;
  1662. int input;
  1663. char instruction;
  1664. order = DEFAULT_ORDER_2;
  1665. verbose_output = false;
  1666. //usage_1();
  1667. //usage_2();
  1668. // ------------------------------------------------------------60
  1669. // get input from file, if file provided
  1670. // ------------------------------------------------------------60
  1671. if (input_file != NULL) {
  1672. printf("Getting input from file %s...\n", argv[1]);
  1673. // open input file
  1674. file_pointer = fopen(input_file, "r");
  1675. if (file_pointer == NULL) {
  1676. perror("Failure to open input file.");
  1677. exit(EXIT_FAILURE);
  1678. }
  1679. // get # of numbers in the file
  1680. fscanf(file_pointer, "%d\n", &input);
  1681. size = input;
  1682. // save all numbers
  1683. while (!feof(file_pointer)) {
  1684. fscanf(file_pointer, "%d\n", &input);
  1685. root = insert(root, input, input);
  1686. }
  1687. // close file
  1688. fclose(file_pointer);
  1689. //print_tree(root);
  1690. //printf("Height of tree = %d\n", height(root));
  1691. }
  1692. else{
  1693. printf("ERROR: Argument -file missing\n");
  1694. return 0;
  1695. }
  1696. // ------------------------------------------------------------60
  1697. // get tree statistics
  1698. // ------------------------------------------------------------60
  1699. printf("Transforming data to a GPU suitable structure...\n");
  1700. long mem_used = transform_to_cuda(root,0);
  1701. maxheight = height(root);
  1702. long rootLoc = (long)knodes - (long)mem;
  1703. // ------------------------------------------------------------60
  1704. // process commands
  1705. // ------------------------------------------------------------60
  1706. char *commandPointer=commandBuffer;
  1707. printf("Waiting for command\n");
  1708. printf("> ");
  1709. while (sscanf(commandPointer, "%c", &instruction) != EOF) {
  1710. commandPointer++;
  1711. switch (instruction) {
  1712. // ----------------------------------------40
  1713. // Insert
  1714. // ----------------------------------------40
  1715. case 'i':
  1716. {
  1717. scanf("%d", &input);
  1718. while (getchar() != (int)'\n');
  1719. root = insert(root, input, input);
  1720. print_tree(root);
  1721. break;
  1722. }
  1723. // ----------------------------------------40
  1724. // n/a
  1725. // ----------------------------------------40
  1726. case 'f':
  1727. {
  1728. }
  1729. // ----------------------------------------40
  1730. // find
  1731. // ----------------------------------------40
  1732. case 'p':
  1733. {
  1734. scanf("%d", &input);
  1735. while (getchar() != (int)'\n');
  1736. r = find(root, input, instruction == 'p');
  1737. if (r == NULL)
  1738. printf("Record not found under key %d.\n", input);
  1739. else
  1740. printf("Record found: %d\n",r->value);
  1741. break;
  1742. }
  1743. // ----------------------------------------40
  1744. // delete value
  1745. // ----------------------------------------40
  1746. case 'd':
  1747. {
  1748. scanf("%d", &input);
  1749. while (getchar() != (int)'\n');
  1750. root = (node *) deleteVal(root, input);
  1751. print_tree(root);
  1752. break;
  1753. }
  1754. // ----------------------------------------40
  1755. // destroy tree
  1756. // ----------------------------------------40
  1757. case 'x':
  1758. {
  1759. while (getchar() != (int)'\n');
  1760. root = destroy_tree(root);
  1761. print_tree(root);
  1762. break;
  1763. }
  1764. // ----------------------------------------40
  1765. // print leaves
  1766. // ----------------------------------------40
  1767. case 'l':
  1768. {
  1769. while (getchar() != (int)'\n');
  1770. print_leaves(root);
  1771. break;
  1772. }
  1773. // ----------------------------------------40
  1774. // print tree
  1775. // ----------------------------------------40
  1776. case 't':
  1777. {
  1778. while (getchar() != (int)'\n');
  1779. print_tree(root);
  1780. break;
  1781. }
  1782. // ----------------------------------------40
  1783. // toggle verbose output
  1784. // ----------------------------------------40
  1785. case 'v':
  1786. {
  1787. while (getchar() != (int)'\n');
  1788. verbose_output = !verbose_output;
  1789. break;
  1790. }
  1791. // ----------------------------------------40
  1792. // quit
  1793. // ----------------------------------------40
  1794. case 'q':
  1795. {
  1796. while (getchar() != (int)'\n');
  1797. return EXIT_SUCCESS;
  1798. }
  1799. // ----------------------------------------40
  1800. // [GPU] find K (initK, findK)
  1801. // ----------------------------------------40
  1802. case 'k':
  1803. {
  1804. // get # of queries from user
  1805. int count;
  1806. sscanf(commandPointer, "%d", &count);
  1807. while(*commandPointer!=32 && commandPointer!='\n')
  1808. commandPointer++;
  1809. printf("\n ******command: k count=%d \n",count);
  1810. if(count > 65535){
  1811. printf("ERROR: Number of requested querries should be 65,535 at most. (limited by # of CUDA blocks)\n");
  1812. exit(0);
  1813. }
  1814. // INPUT: records CPU allocation (setting pointer in mem variable)
  1815. record *records = (record *)mem;
  1816. long records_elem = (long)rootLoc / sizeof(record);
  1817. long records_mem = (long)rootLoc;
  1818. printf("records_elem=%d, records_unit_mem=%d, records_mem=%d\n", (int)records_elem, (int)sizeof(record), (int)records_mem);
  1819. // INPUT: knodes CPU allocation (setting pointer in mem variable)
  1820. knode *knodes = (knode *)((long)mem + (long)rootLoc);
  1821. long knodes_elem = ((long)(mem_used) - (long)rootLoc) / sizeof(knode);
  1822. long knodes_mem = (long)(mem_used) - (long)rootLoc;
  1823. printf("knodes_elem=%d, knodes_unit_mem=%d, knodes_mem=%d\n", (int)knodes_elem, (int)sizeof(knode), (int)knodes_mem);
  1824. // INPUT: currKnode CPU allocation
  1825. long *currKnode;
  1826. currKnode = (long *)malloc(count*sizeof(long));
  1827. // INPUT: offset CPU initialization
  1828. memset(currKnode, 0, count*sizeof(long));
  1829. // INPUT: offset CPU allocation
  1830. long *offset;
  1831. offset = (long *)malloc(count*sizeof(long));
  1832. // INPUT: offset CPU initialization
  1833. memset(offset, 0, count*sizeof(long));
  1834. // INPUT: keys CPU allocation
  1835. int *keys;
  1836. keys = (int *)malloc(count*sizeof(int));
  1837. // INPUT: keys CPU initialization
  1838. int i;
  1839. for(i = 0; i < count; i++){
  1840. keys[i] = (rand()/(float)RAND_MAX)*size;
  1841. }
  1842. // OUTPUT: ans CPU allocation
  1843. record *ans = (record *)malloc(sizeof(record)*count);
  1844. // OUTPUT: ans CPU initialization
  1845. for(i = 0; i < count; i++){
  1846. ans[i].value = -1;
  1847. }
  1848. // OpenCL kernel
  1849. kernel_gpu_opencl_wrapper( records,
  1850. records_mem,
  1851. knodes,
  1852. knodes_elem,
  1853. knodes_mem,
  1854. order,
  1855. maxheight,
  1856. count,
  1857. currKnode,
  1858. offset,
  1859. keys,
  1860. ans);
  1861. pFile = fopen (output,"aw+");
  1862. if (pFile==NULL)
  1863. {
  1864. fputs ("Fail to open %s !\n",output);
  1865. }
  1866. fprintf(pFile,"\n ******command: k count=%d \n",count);
  1867. for(i = 0; i < count; i++){
  1868. fprintf(pFile, "%d %d\n",i, ans[i].value);
  1869. }
  1870. fprintf(pFile, " \n");
  1871. fclose(pFile);
  1872. // free memory
  1873. free(currKnode);
  1874. free(offset);
  1875. free(keys);
  1876. free(ans);
  1877. // break out of case
  1878. break;
  1879. }
  1880. // ----------------------------------------40
  1881. // find range
  1882. // ----------------------------------------40
  1883. case 'r':
  1884. {
  1885. int start, end;
  1886. scanf("%d", &start);
  1887. scanf("%d", &end);
  1888. if(start > end){
  1889. input = start;
  1890. start = end;
  1891. end = input;
  1892. }
  1893. printf("For range %d to %d, ",start,end);
  1894. list_t * ansList;
  1895. ansList = findRange(root, start, end);
  1896. printf("%d records found\n", list_get_length(ansList));
  1897. //list_iterator_t iter;
  1898. free(ansList);
  1899. break;
  1900. }
  1901. // ----------------------------------------40
  1902. // [GPU] find Range K (initK, findRangeK)
  1903. // ----------------------------------------40
  1904. case 'j':
  1905. {
  1906. // get # of queries from user
  1907. int count;
  1908. sscanf(commandPointer, "%d", &count);
  1909. while(*commandPointer!=32 && commandPointer!='\n')
  1910. commandPointer++;
  1911. int rSize;
  1912. sscanf(commandPointer, "%d", &rSize);
  1913. while(*commandPointer!=32 && commandPointer!='\n')
  1914. commandPointer++;
  1915. printf("\n******command: j count=%d, rSize=%d \n",count, rSize);
  1916. if(rSize > size || rSize < 0) {
  1917. printf("Search range size is larger than data set size %d.\n", (int)size);
  1918. exit(0);
  1919. }
  1920. // INPUT: knodes CPU allocation (setting pointer in mem variable)
  1921. knode *knodes = (knode *)((long)mem + (long)rootLoc);
  1922. long knodes_elem = ((long)(mem_used) - (long)rootLoc) / sizeof(knode);
  1923. long knodes_mem = (long)(mem_used) - (long)rootLoc;
  1924. printf("knodes_elem=%d, knodes_unit_mem=%d, knodes_mem=%d\n", (int)knodes_elem, (int)sizeof(knode), (int)knodes_mem);
  1925. // INPUT: currKnode CPU allocation
  1926. long *currKnode;
  1927. currKnode = (long *)malloc(count*sizeof(long));
  1928. // INPUT: offset CPU initialization
  1929. memset (currKnode, 0, count*sizeof(long));
  1930. // INPUT: offset CPU allocation
  1931. long *offset;
  1932. offset = (long *)malloc(count*sizeof(long));
  1933. // INPUT: offset CPU initialization
  1934. memset (offset, 0, count*sizeof(long));
  1935. // INPUT: lastKnode CPU allocation
  1936. long *lastKnode;
  1937. lastKnode = (long *)malloc(count*sizeof(long));
  1938. // INPUT: offset CPU initialization
  1939. memset (lastKnode, 0, count*sizeof(long));
  1940. // INPUT: offset_2 CPU allocation
  1941. long *offset_2;
  1942. offset_2 = (long *)malloc(count*sizeof(long));
  1943. // INPUT: offset CPU initialization
  1944. memset (offset_2, 0, count*sizeof(long));
  1945. // INPUT: start, end CPU allocation
  1946. int *start;
  1947. start = (int *)malloc(count*sizeof(int));
  1948. int *end;
  1949. end = (int *)malloc(count*sizeof(int));
  1950. // INPUT: start, end CPU initialization
  1951. int i;
  1952. for(i = 0; i < count; i++){
  1953. start[i] = (rand()/(float)RAND_MAX)*size;
  1954. end[i] = start[i]+rSize;
  1955. if(end[i] >= size){
  1956. start[i] = start[i] - (end[i] - size);
  1957. end[i]= size-1;
  1958. }
  1959. }
  1960. // INPUT: recstart, reclenght CPU allocation
  1961. int *recstart;
  1962. recstart = (int *)malloc(count*sizeof(int));
  1963. int *reclength;
  1964. reclength = (int *)malloc(count*sizeof(int));
  1965. // OUTPUT: ans CPU initialization
  1966. for(i = 0; i < count; i++){
  1967. recstart[i] = 0;
  1968. reclength[i] = 0;
  1969. }
  1970. // CUDA kernel
  1971. kernel_gpu_opencl_wrapper_2(knodes,
  1972. knodes_elem,
  1973. knodes_mem,
  1974. order,
  1975. maxheight,
  1976. count,
  1977. currKnode,
  1978. offset,
  1979. lastKnode,
  1980. offset_2,
  1981. start,
  1982. end,
  1983. recstart,
  1984. reclength);
  1985. pFile = fopen (output,"aw+");
  1986. if (pFile==NULL)
  1987. {
  1988. fputs ("Fail to open %s !\n",output);
  1989. }
  1990. fprintf(pFile,"\n******command: j count=%d, rSize=%d \n",count, rSize);
  1991. for(i = 0; i < count; i++){
  1992. fprintf(pFile, "%d %d %d\n",i, recstart[i],reclength[i]);
  1993. }
  1994. fprintf(pFile, " \n");
  1995. fclose(pFile);
  1996. // free memory
  1997. free(currKnode);
  1998. free(offset);
  1999. free(lastKnode);
  2000. free(offset_2);
  2001. free(start);
  2002. free(end);
  2003. free(recstart);
  2004. free(reclength);
  2005. // break out of case
  2006. break;
  2007. }
  2008. // ----------------------------------------40
  2009. // default
  2010. // ----------------------------------------40
  2011. default:
  2012. {
  2013. //usage_2();
  2014. break;
  2015. }
  2016. }
  2017. printf("> ");
  2018. }
  2019. printf("\n");
  2020. // ------------------------------------------------------------60
  2021. // free remaining memory and exit
  2022. // ------------------------------------------------------------60
  2023. free(mem);
  2024. return EXIT_SUCCESS;
  2025. }
  2026. //========================================================================================================================================================================================================200
  2027. // END
  2028. //========================================================================================================================================================================================================200
  2029. // # ifdef __cplusplus
  2030. // }
  2031. // # endif