Example #1
0
/* 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;
}
Example #2
0
  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);
  }
Example #3
0
// 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);
}
Example #4
0
	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)
Example #5
0
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;
    }
}
Example #6
0
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;
}