Advertisement
Guest User

Untitled

a guest
May 2nd, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.60 KB | None | 0 0
  1. //===============Inserção========================================
  2.  
  3. //encontra o ponto de corte para particionar em dois um nó que é grande demais
  4.  
  5. int cut(int order){
  6. //se a ordem for par, retorna o índice do meio
  7. if(order %2 == 0){
  8. return order/2;
  9. }
  10. else{//se não, retorna o indice do meio mais um
  11. return order/2 + 1;
  12. }
  13. }
  14.  
  15. /*Cria um novo registro*/
  16. record * make_record(char **rec, int size, int key_id){
  17. record* new_record = (record*)malloc(sizeof(record));
  18. new_record->size = size;
  19. new_record->key = strtoull(rec[key_id], NULL, 0);
  20.  
  21. int i;
  22. new_record->fields = malloc(size*(sizeof(char)*30));//aloca espaço para cada campo do vetor
  23. for (i = 0; i < size; i++){
  24. new_record->fields[i] = rec[i];
  25. }
  26. return new_record;
  27. }
  28.  
  29. /*Cria um nó vazio que pode ser adaptado para ser uma folha ou um nó interno*/
  30. node * make_node(int order){
  31. node * new_node;
  32. new_node = malloc(sizeof(node));
  33. new_node->keys = malloc(order * sizeof(unsigned long long int));
  34. new_node->pointers = malloc((order+1)*sizeof(void *)); // esses ponteiros podem ser de registros ou de nós, por isso usei void
  35. new_node->is_leaf = false;
  36. new_node->num_keys = 0;
  37. new_node->parent = NULL;
  38. new_node->next = NULL;
  39. new_node->order = order;
  40. return new_node;
  41. }
  42.  
  43. /*Adapta um nó para que ele seja uma folha*/
  44. node * make_leaf(int order){
  45. node* leaf = make_node(order);
  46. leaf->is_leaf = true;
  47. return leaf;
  48. }
  49.  
  50. /*Essa função encontra no vetor de chaves do nó mãe
  51. o indice do nó a esquerda do nó onde a chave vai ser inserida*/
  52. int get_left_index(node * parent, node * left){
  53. int left_index = 0;
  54. //começa na chave 0 do pai e caminha até encontrar o nó da esquerda
  55. while(left_index <= parent->num_keys && parent->pointers[left_index] != left){
  56. left_index++;
  57. }
  58.  
  59. return left_index;
  60. }
  61.  
  62. /*Insere em uma folha uma chave e um ponteiro para seu registro correspondente.
  63. Retorna a folha alterada*/
  64. node * insert_into_leaf(node * leaf, unsigned long long key, record * pointer){
  65. int i;
  66. int insertion_point = 0;
  67.  
  68. // caminha no vetor de chaves da folha até encontrar o índice onde a chave deve ser inserida
  69. while(insertion_point < leaf->num_keys && leaf->keys[insertion_point] < key){
  70. insertion_point ++;
  71. }
  72.  
  73. /*caminha da última chave no vetor até o ponto de inseção
  74. movendo as chaves e os registros um índice para frente para que haja espaço
  75. para a nova chave e para o novo registro
  76. */
  77. for(i = leaf->num_keys; i > insertion_point; i--){
  78. leaf->keys[i] = leaf->keys[i-1];
  79. leaf->pointers[i] = leaf->pointers[i-1];
  80. }
  81.  
  82. //insere a nova chave e registro no espaço recentemente aberto
  83. leaf->keys[insertion_point] = key;
  84. leaf->pointers[insertion_point] = pointer;
  85. leaf->num_keys ++;
  86.  
  87. return leaf;
  88. }
  89.  
  90. /*Insere em uma folha cheia uma nova chave e um ponteiro para registro,
  91. de forma q ultrapasse o tamanho máximo e q a folha seja dividida em duas*/
  92. node * insert_into_leaf_after_splitting(node * root, node * leaf, unsigned long long int key, record * pointer){
  93. node * new_leaf;
  94. void ** temp_pointers;
  95. unsigned long long int * temp_keys;
  96. unsigned long long int new_key;
  97. int insertion_point, split, i, j, ord;
  98.  
  99. ord = root->order;
  100.  
  101. new_leaf = make_leaf(ord);
  102.  
  103. temp_keys = malloc(ord * sizeof(unsigned long long int));
  104. temp_pointers = malloc(ord * sizeof(void*));
  105.  
  106. //caminha no vetor de chaves da folha procurando o ponto de inserção da nova chave
  107. insertion_point = 0;
  108. while(insertion_point < (ord - 1) && leaf->keys[insertion_point] < key){
  109. insertion_point ++;
  110. }
  111.  
  112. /*caminha no índice tanto dos vetores temporarios quanto nos originais até achar o ponto de inserção
  113. quando o encontra ela aumenta apenas o j de forma q o índice de inserção seja pulado e as chaves e registros seja movidos
  114. um indice para frente, deixando o espaço para o novo registro
  115. */
  116. for(i = 0, j = 0; i < leaf->num_keys; i++, j ++){
  117. if(j == insertion_point){
  118. j++;
  119. }
  120. temp_keys[j] = leaf->keys[i];
  121. temp_pointers[j] = leaf->pointers[i];
  122. }
  123.  
  124. temp_keys[insertion_point] = key;
  125. temp_pointers[insertion_point] = pointer;
  126.  
  127. leaf->num_keys =0;
  128. //encontra o ponto onde os vetores devem ser divididos
  129. split = cut(ord-1);
  130.  
  131. //copia e cola a primeira metade das chaves e registros na folha
  132. for(i = 0; i < split; i++){
  133. leaf->pointers[i] = temp_pointers[i];
  134. leaf->keys[i] = temp_keys[i];
  135. leaf->num_keys ++;
  136. }
  137.  
  138. //copia e cola a segunda metade das chaves e registros na nova folha
  139. for(i = split, j = 0; i < ord; i++, j ++){
  140. new_leaf-> pointers[j] = new_leaf->pointers[i];
  141. new_leaf->keys[j] = temp_keys[i];
  142. new_leaf->num_keys ++;
  143. }
  144.  
  145. free(temp_pointers);
  146. free(temp_keys);
  147.  
  148. /*o último ponteiro da nova folha vai apontar para a folha cujo ultimo ponteiro da folha antiga costumava apontar
  149. e o ultimo ponteiro da folha antiga agora vai apontar para a nova folha*/
  150. new_leaf->pointers[ord - 1] = leaf->pointers[ord - 1];
  151. leaf->pointers[ord - 1] = new_leaf;
  152.  
  153. //limpa os índices q não estão sendo usados em ambas as folhas
  154. for(i = leaf->num_keys ; i < ord - 1; i++){
  155. leaf->pointers[i] = NULL;
  156. }
  157. for(i = new_leaf->num_keys; i <ord - 1; i ++){
  158. new_leaf->pointers[i] = NULL;
  159. }
  160.  
  161. /*coloca a mãe da folha antiga como mãe da folha nova
  162. e coloca a primeira chave da nova folha como a chave do nó-folha */
  163. new_leaf->parent = leaf->parent;
  164. new_key = new_leaf->keys[0];
  165.  
  166. //e finalmente insere a nova folha no nó mãe
  167. return insert_into_parent(root, leaf, key, new_leaf);
  168. }
  169.  
  170. /*Insere em um nó uma nova chave e um noov ponteiro de nó filho
  171. sem que isso torne o nó grande demais*/
  172.  
  173. node * insert_into_node(node * root, node * n, int left_index, unsigned long long int key, node * right){
  174. int i;
  175.  
  176. /*caminha da ultima chave inserida no nó até o indice depois do esquerdo
  177. e passa as chaves já inseridas um índice para frente de forma q o índice depois do esquerdo
  178. fique livre para uso*/
  179. for(i = n->num_keys; i > left_index; i --){
  180. n->pointers[i+1] = n->pointers[i];
  181. n->keys[i] = n->keys[i -1];
  182. }
  183.  
  184. n->pointers[left_index +1] = right; //insere a referencia para o novo nó apos o indice da esquerda do nó antigo
  185. n->keys[left_index] = key;
  186. n->num_keys ++;
  187.  
  188. return root;
  189. }
  190.  
  191. /*Insere em um nó uma nova chave e ponteiro para nó filho de forma que
  192. o nó se torne grande demais e seja particionado em 2*/
  193.  
  194. node * insert_into_node_after_splitting(node * root, node * old_node, int left_index, unsigned long long int key, node * right){
  195.  
  196. int i, j, split, k_prime;
  197. int ord = root->order;
  198. node * new_node;
  199. node *child;
  200. unsigned long long int * temp_keys;
  201. node ** temp_pointers;
  202.  
  203. /*Criamos um vetor de chaves e um vetor de ponteiros para armazenar toda a informação na ordem certa
  204. e depois criamos um novo nó e copiamos no nó antigo metado das chaves e metade dos ponteiros
  205. e no nó novo a outra metade*/
  206.  
  207. temp_pointers = malloc((ord + 1)* sizeof(node *));
  208. temp_keys = malloc((ord + 1)* sizeof(unsigned long long int));
  209.  
  210. //percorre o nó antigo gravando cada ponteiro no vetor de nós filhos temporario
  211. //quando chega no indice onde do ponteiro novo será inserido ele pula o indice
  212. for(i = 0, j = 0; i < old_node->num_keys + 1; i++, j++){
  213. if(j == left_index + 1){
  214. j ++;
  215. }
  216. temp_pointers[j] = old_node->pointers[i];
  217. }
  218.  
  219. //faz a mesma coisa para o vetor de chaves
  220. for(i =0,j=0; i <old_node->num_keys; i++, j++){
  221. if(j == left_index){
  222. j++;
  223. }
  224. temp_keys[j] = old_node->keys[i];
  225. }
  226.  
  227. /*Cria um novo nó e copia metade das chaves e ponteiros para ele
  228. e a outra metade para o nó antigo*/
  229. split = cut(ord);
  230. new_node = make_node(ord);
  231. old_node->num_keys = 0;
  232.  
  233. //copia a primeira metade das chaves e ponteiros para o nó antigo
  234. for(i = 0; i <split - 1; i++){
  235. old_node->pointers[i] = temp_pointers[i];
  236. old_node->keys[i] = temp_keys[i];
  237. old_node->num_keys ++;
  238. }
  239. old_node->pointers[i] = temp_pointers[i];
  240.  
  241. //armazena a chave do final do nó com as menores chaves
  242. //isso vai ser usado depois para inserir essa chave no pai dos 2 nós, essa é a chave q sobe
  243. k_prime = temp_keys[split - 1];
  244.  
  245. //i começa como o pŕoximo indice depois do ultimo inserido no nó antigo
  246. /*copia a segunda metade das chaves e ponteiros e cola no novo nó*/
  247. for(++ i, j =0; i <ord; i ++, j ++ ){
  248. new_node->pointers[j] = temp_pointers[i];
  249. new_node->keys[j] = temp_keys[i];
  250. new_node->num_keys ++;
  251. }
  252.  
  253.  
  254. new_node->pointers[j] = temp_pointers[i];
  255. free(temp_pointers);
  256. free(temp_keys);
  257. new_node->parent = old_node->parent;
  258.  
  259. //caminha pelos nós filhos do novo nó e faz com que cada um deles tenha a referencia do nó mãe como parent
  260. for(i = 0; i <= new_node->num_keys; i++){
  261. child = new_node->pointers[i];
  262. child->parent = new_node;
  263. }
  264.  
  265. /*e finalmente insere uma nova chave no nó mãe dos dois nós gerados pela partição
  266. o velho a esquerda e o novo a direita
  267. */
  268. return insert_into_parent(root, old_node, k_prime, new_node);
  269. }
  270.  
  271.  
  272. /*Insere um novo nó(ou folha) na árvore
  273. retorna a raiz da árvore depois da inserção*/
  274.  
  275. node * insert_into_parent(node * root, node * left, unsigned long long int key, node * right){
  276.  
  277. int left_index;
  278. int ord = root->order;
  279. node * parent;
  280.  
  281. parent = left->parent;
  282.  
  283. /*Caso número 1: Uma nova raiz*/
  284. if(parent == NULL){
  285. return insert_into_new_root(left, key, right);
  286. }
  287.  
  288. /*Caso número 2: Uma folha ou um nó*/
  289.  
  290. //procuramos no nó mãe o ponteiro para o nó da esquerda
  291. left_index = get_left_index(parent, left);
  292.  
  293. //A nova chave cabe no nó sem estourar ele
  294. if(parent->num_keys < (ord-1)){
  295. return insert_into_node(root, parent, left_index, key, right);
  296. }
  297.  
  298. //A nova chave vai estourar o nó, precisamos dividi-lo em 2
  299. return insert_into_node_after_splitting(root, parent, left_index, key, right);
  300. }
  301.  
  302. /*Cria uma nova raiz para 2 sub-árvores
  303. e depois insere a chave correta na nova raiz*/
  304.  
  305. node * insert_into_new_root(node * left, unsigned long long int key, node * right){
  306.  
  307. int ord = left->order;
  308. node * root = make_node(ord);
  309. root->keys[0] = key;
  310. root->pointers[0] =left;
  311. root->pointers[1] = right;
  312. root->num_keys++;
  313. root->parent = NULL;
  314. left->parent = root;
  315. right->parent = root;
  316. return root;
  317. }
  318.  
  319. /*Primeira inserção, começando uma nova árvore!*/
  320. node * start_new_tree(unsigned long long int key, record * pointer, int order){
  321.  
  322. node * root = make_leaf(order);
  323. root->keys[0] = key;
  324. root->pointers[0] = pointer;
  325. root->pointers[order -1] = NULL;
  326. root->parent = NULL;
  327. root->num_keys ++;
  328. root->order = order;
  329. return root;
  330. }
  331.  
  332. /*Função principal de inserção
  333. insere na árvore uma chave e seu ponteiro de registro ou nó filho*/
  334. //é o ponto de entrada de todos os tipos de inserção e é chamada pela main
  335. node * insert(node * root, unsigned long long int key, char **rec, int size, int key_id, int order){
  336.  
  337. record * pointer;
  338. node * leaf;
  339.  
  340. /*Se a chave já existe*/
  341. if (find_rec(root, key) != NULL){
  342. return root;
  343. }
  344.  
  345. /*Cria um novo registro com os valores dados*/
  346. pointer = make_record(rec, size, key_id);
  347.  
  348.  
  349. /*Se a árvore não existe ainda*/
  350. if(root == NULL){
  351. return start_new_tree(key, pointer, order);
  352. }
  353.  
  354. /*Se a árvore existe*/
  355.  
  356. //encontramos uma folha
  357. leaf = find_leaf(root, key);
  358.  
  359. /*Se a folha tem espaço para a chave e ponteiro*/
  360. if(leaf->num_keys < order -1){
  361. leaf = insert_into_leaf(leaf, key, pointer);
  362. return root;
  363. }
  364.  
  365. /*A folha precisa ser dividida em 2*/
  366. return insert_into_leaf_after_splitting(root, leaf, key, pointer);
  367.  
  368. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement