/* First insertion: * start a new tree. */ node * start_new_tree(int key, record * pointer) { node * root = make_leaf(); root->keys[0] = key; root->pointers[0] = pointer; root->pointers[order - 1] = NULL; root->parent = NULL; root->num_keys++; return root; }
uint build_helper(std::vector<Node>& tree, const Pos& pos) { // parse nodes in the depth first order if (vt_(pos.first, pos.second)==static_cast<uint>(-1)) { if (pos.first==pos.second) { make_leaf(tree, pos); } else if (bp_(pos).empty()) { make_loop(tree, pos); } else { make_stem(tree, pos); } } return vt_(pos.first, pos.second); }
// 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. node * insert_into_leaf_after_splitting(node * root, node * leaf, int key, record * pointer) { node * new_leaf; int * temp_keys; void ** temp_pointers; int insertion_index, split, new_key, i, j; new_leaf = make_leaf(); temp_keys = malloc( order * sizeof(int) ); if (temp_keys == NULL) { perror("Temporary keys array."); exit(EXIT_FAILURE); } temp_pointers = malloc( order * sizeof(void *) ); if (temp_pointers == NULL) { perror("Temporary pointers array."); exit(EXIT_FAILURE); } insertion_index = 0; while (insertion_index < order - 1 && leaf->keys[insertion_index] < key) insertion_index++; for (i = 0, j = 0; i < leaf->num_keys; i++, j++) { if (j == insertion_index) j++; temp_keys[j] = leaf->keys[i]; temp_pointers[j] = leaf->pointers[i]; } temp_keys[insertion_index] = key; temp_pointers[insertion_index] = pointer; leaf->num_keys = 0; split = cut(order - 1); for (i = 0; i < split; i++) { leaf->pointers[i] = temp_pointers[i]; leaf->keys[i] = temp_keys[i]; leaf->num_keys++; } for (i = split, j = 0; i < order; i++, j++) { new_leaf->pointers[j] = temp_pointers[i]; new_leaf->keys[j] = temp_keys[i]; new_leaf->num_keys++; } free(temp_pointers); free(temp_keys); new_leaf->pointers[order - 1] = leaf->pointers[order - 1]; leaf->pointers[order - 1] = new_leaf; for (i = leaf->num_keys; i < order - 1; i++) leaf->pointers[i] = NULL; for (i = new_leaf->num_keys; i < order - 1; i++) new_leaf->pointers[i] = NULL; new_leaf->parent = leaf->parent; new_key = new_leaf->keys[0]; return insert_into_parent(root, leaf, new_key, new_leaf); }
return insert_into_leaf_after_splitting(root, leaf, key, pointer); } node * insert_into_leaf_after_splitting(node * root, node * leaf, int key, record * pointer) { printf("\ ninsert_into_leaf_after_splitting"); node * new_leaf; int * temp_keys; void ** temp_pointers; int insertion_index, split, new_key, i, j; new_leaf = make_leaf(); temp_keys = malloc( order * sizeof(int) ); if (temp_keys == NULL) { perror("Temporary keys array."); exit(EXIT_FAILURE); } temp_pointers = malloc( order * sizeof(void *) ); if (temp_pointers == NULL) { perror("Temporary pointers array."); exit(EXIT_FAILURE); } insertion_index = 0; while (insertion_index < order - 1 && leaf->keys[insertion_index] < key)
TREE *csoundParseOrc(CSOUND *csound, const char *str) { int err; OPARMS *O = csound->oparms; csound->parserNamedInstrFlag = 2; { PRE_PARM qq; /* Preprocess */ memset(&qq, 0, sizeof(PRE_PARM)); //csp_orc_sa_print_list(csound); csound_prelex_init(&qq.yyscanner); csound_preset_extra(&qq, qq.yyscanner); qq.line = csound->orcLineOffset; csound->expanded_orc = corfile_create_w(); file_to_int(csound, "**unknown**"); if (str == NULL) { char bb[80]; if (csound->orchstr==NULL && !csound->oparms->daemon) csound->Die(csound, Str("Failed to open input file %s\n"), csound->orchname); else if(csound->orchstr==NULL && csound->oparms->daemon) return NULL; add_include_udo_dir(csound->orchstr); if (csound->orchname==NULL || csound->orchname[0]=='\0') csound->orchname = csound->csdname; /* We know this is the start so stack is empty so far */ snprintf(bb, 80, "#source %d\n", qq.lstack[0] = file_to_int(csound, csound->orchname)); corfile_puts(bb, csound->expanded_orc); snprintf(bb, 80, "#line %d\n", csound->orcLineOffset); corfile_puts(bb, csound->expanded_orc); } else { if (csound->orchstr == NULL || corfile_body(csound->orchstr) == NULL) csound->orchstr = corfile_create_w(); else corfile_reset(csound->orchstr); corfile_puts(str, csound->orchstr); corfile_puts("\n#exit\n", csound->orchstr); corfile_putc('\0', csound->orchstr); corfile_putc('\0', csound->orchstr); } csound->DebugMsg(csound, "Calling preprocess on >>%s<<\n", corfile_body(csound->orchstr)); //csound->DebugMsg(csound,"FILE: %s \n", csound->orchstr->body); // csound_print_preextra(&qq); cs_init_math_constants_macros(csound, &qq); cs_init_omacros(csound, &qq, csound->omacros); // csound_print_preextra(&qq); csound_prelex(csound, qq.yyscanner); if (UNLIKELY(qq.ifdefStack != NULL)) { csound->Message(csound, Str("Unmatched #ifdef\n")); csound->LongJmp(csound, 1); } csound_prelex_destroy(qq.yyscanner); csound->DebugMsg(csound, "yielding >>%s<<\n", corfile_body(csound->expanded_orc)); corfile_rm(&csound->orchstr); } { /* VL 15.3.2015 allocating memory here will cause unwanted growth. We just pass a pointer, which will be allocated by make leaf */ TREE* astTree = NULL;// = (TREE *)csound->Calloc(csound, sizeof(TREE)); TREE* newRoot; PARSE_PARM pp; TYPE_TABLE* typeTable = NULL; /* Parse */ memset(&pp, '\0', sizeof(PARSE_PARM)); init_symbtab(csound); csound_orcdebug = O->odebug; csound_orclex_init(&pp.yyscanner); csound_orcset_extra(&pp, pp.yyscanner); csound_orc_scan_buffer(corfile_body(csound->expanded_orc), corfile_tell(csound->expanded_orc), pp.yyscanner); //csound_orcset_lineno(csound->orcLineOffset, pp.yyscanner); //printf("%p \n", astTree); err = csound_orcparse(&pp, pp.yyscanner, csound, &astTree); //printf("%p \n", astTree); // print_tree(csound, "AST - AFTER csound_orcparse()\n", astTree); //csp_orc_sa_cleanup(csound); corfile_rm(&csound->expanded_orc); if (csound->synterrcnt) err = 3; if (LIKELY(err == 0)) { if(csound->oparms->odebug) csound->Message(csound, Str("Parsing successful!\n")); } else { if (err == 1){ csound->Message(csound, Str("Parsing failed due to invalid input!\n")); } else if (err == 2){ csound->Message(csound, Str("Parsing failed due to memory exhaustion!\n")); } else if (err == 3){ csound->Message(csound, Str("Parsing failed due to %d syntax error%s!\n"), csound->synterrcnt, csound->synterrcnt==1?"":"s"); } goto ending; } if (UNLIKELY(PARSER_DEBUG)) { print_tree(csound, "AST - INITIAL\n", astTree); } //print_tree(csound, "AST - INITIAL\n", astTree); typeTable = csound->Malloc(csound, sizeof(TYPE_TABLE)); typeTable->udos = NULL; typeTable->globalPool = csoundCreateVarPool(csound); typeTable->instr0LocalPool = csoundCreateVarPool(csound); typeTable->localPool = typeTable->instr0LocalPool; typeTable->labelList = NULL; /**** THIS NEXT LINE IS WRONG AS err IS int WHILE FN RETURNS TREE* ****/ astTree = verify_tree(csound, astTree, typeTable); // csound->Free(csound, typeTable->instr0LocalPool); // csound->Free(csound, typeTable->globalPool); // csound->Free(csound, typeTable); //print_tree(csound, "AST - FOLDED\n", astTree); //FIXME - synterrcnt should not be global if (astTree == NULL || csound->synterrcnt){ err = 3; if (astTree) csound->Message(csound, Str("Parsing failed due to %d semantic error%s!\n"), csound->synterrcnt, csound->synterrcnt==1?"":"s"); else if (csound->synterrcnt) csound->Message(csound, Str("Parsing failed to syntax errors\n")); else csound->Message(csound, Str("Parsing failed due no input!\n")); goto ending; } err = 0; //csp_orc_analyze_tree(csound, astTree); // astTree = csound_orc_expand_expressions(csound, astTree); // if (UNLIKELY(PARSER_DEBUG)) { print_tree(csound, "AST - AFTER VERIFICATION/EXPANSION\n", astTree); } ending: csound_orclex_destroy(pp.yyscanner); if (err) { csound->ErrorMsg(csound, Str("Stopping on parser failure")); csoundDeleteTree(csound, astTree); if (typeTable != NULL) { csoundFreeVarPool(csound, typeTable->globalPool); if(typeTable->instr0LocalPool != NULL) { csoundFreeVarPool(csound, typeTable->instr0LocalPool); } if(typeTable->localPool != typeTable->instr0LocalPool) { csoundFreeVarPool(csound, typeTable->localPool); } csound->Free(csound, typeTable); } return NULL; } astTree = csound_orc_optimize(csound, astTree); // small hack: use an extra node as head of tree list to hold the // typeTable, to be used during compilation newRoot = make_leaf(csound, 0, 0, 0, NULL); newRoot->markup = typeTable; newRoot->next = astTree; /* if(str!=NULL){ */ /* if (typeTable != NULL) { */ /* csoundFreeVarPool(csound, typeTable->globalPool); */ /* if(typeTable->instr0LocalPool != NULL) { */ /* csoundFreeVarPool(csound, typeTable->instr0LocalPool); */ /* } */ /* if(typeTable->localPool != typeTable->instr0LocalPool) { */ /* csoundFreeVarPool(csound, typeTable->localPool); */ /* } */ /* csound->Free(csound, typeTable); */ /* } */ /* } */ return newRoot; } }
static void* recursive_insert(art_node *n, art_node **ref, const unsigned char *key, int key_len, void *value, int depth, int *old) { // If we are at a NULL node, inject a leaf if (!n) { *ref = (art_node*)SET_LEAF(make_leaf(key, key_len, value)); return NULL; } // If we are at a leaf, we need to replace it with a node if (IS_LEAF(n)) { art_leaf *l = LEAF_RAW(n); // Check if we are updating an existing value if (!leaf_matches(l, key, key_len, depth)) { *old = 1; void *old_val = l->value; l->value = value; return old_val; } // New value, we must split the leaf into a node4 art_node4 *new_node = (art_node4*)alloc_node(NODE4); // Create a new leaf art_leaf *l2 = make_leaf(key, key_len, value); // Determine longest prefix int longest_prefix = longest_common_prefix(l, l2, depth); new_node->n.partial_len = longest_prefix; memcpy(new_node->n.partial, key+depth, min(MAX_PREFIX_LEN, longest_prefix)); // Add the leafs to the new node4 *ref = (art_node*)new_node; add_child4(new_node, ref, l->key[depth+longest_prefix], SET_LEAF(l)); add_child4(new_node, ref, l2->key[depth+longest_prefix], SET_LEAF(l2)); return NULL; } // Check if given node has a prefix if (n->partial_len) { // Determine if the prefixes differ, since we need to split int prefix_diff = prefix_mismatch(n, key, key_len, depth); if ((uint32_t)prefix_diff >= n->partial_len) { depth += n->partial_len; goto RECURSE_SEARCH; } // Create a new node art_node4 *new_node = (art_node4*)alloc_node(NODE4); *ref = (art_node*)new_node; new_node->n.partial_len = prefix_diff; memcpy(new_node->n.partial, n->partial, min(MAX_PREFIX_LEN, prefix_diff)); // Adjust the prefix of the old node if (n->partial_len <= MAX_PREFIX_LEN) { add_child4(new_node, ref, n->partial[prefix_diff], n); n->partial_len -= (prefix_diff+1); memmove(n->partial, n->partial+prefix_diff+1, min(MAX_PREFIX_LEN, n->partial_len)); } else { n->partial_len -= (prefix_diff+1); art_leaf *l = minimum(n); add_child4(new_node, ref, l->key[depth+prefix_diff], n); memcpy(n->partial, l->key+depth+prefix_diff+1, min(MAX_PREFIX_LEN, n->partial_len)); } // Insert the new leaf art_leaf *l = make_leaf(key, key_len, value); add_child4(new_node, ref, key[depth+prefix_diff], SET_LEAF(l)); return NULL; } RECURSE_SEARCH:; // Find a child to recurse to art_node **child = find_child(n, key[depth]); if (child) { return recursive_insert(*child, child, key, key_len, value, depth+1, old); } // No child, node goes within us art_leaf *l = make_leaf(key, key_len, value); add_child(n, ref, key[depth], SET_LEAF(l)); return NULL; }