int main(int argc, char *argv[])
{
	if (argc > 1)
	{
		unsigned i;
		const unsigned nbArgs = argc;

		for (i = 1; i < nbArgs; ++i)
		{
			if (!strncmp(argv[i],"-debug",6))				/* FLAW */
			{
				debug = true;
				printf("Move to debugging mode\n");
				// for debugging code and process, let's say you need root rights
				if (strlen(argv[i]) >= 11 && !strncmp(argv[i]+6,":root",5))
				{
					promote_root();
				}
			}
		}	
	}
	else
	{
		printf("No args...\n");
	}

	return 0;
}
Beispiel #2
0
// internal function to write keys
static void write_key(btree * btree,
                      search_result * insert_info,
                      btree_key_t key,
                      btree_data_t datum)
{
    // check to see if page is full
    if (insert_info->m_page->m_key_count == btree->m_order)
    {
        // temporary arrays
        btree_key_t  * temp_keys = (btree_key_t *)malloc(sizeof(btree_key_t) * (btree->m_order + 1));
        btree_data_t * temp_data = (btree_data_t *)malloc(sizeof(btree_data_t) * (btree->m_order + 1));

        // store new item
        temp_keys[insert_info->m_index] = key;
        temp_data[insert_info->m_index] = datum;

        // copy entries from insertion page to temps
        // TODO: change these to use pointers instead of indexes?
        int nt = 0; // index for temp arrays
        int ni = 0; // index for insertion page

        while (ni < btree->m_order)
        {
            // skip over inserted data
            if (ni == insert_info->m_index)
                ++nt;

            // copy data
            temp_keys[nt] = insert_info->m_page->m_keys[ni];
            temp_data[nt] = insert_info->m_page->m_data[ni];

            // next one
            ++ni;
            ++nt;
        }

        // create a new leaf
        btree_page * page_sibling = alloc_page(btree);

        // assign parent        
        page_sibling->m_parent = insert_info->m_page->m_parent;

        // clear key counts
        insert_info->m_page->m_key_count = 0;
        page_sibling->m_key_count        = 0;

        // copy keys from temp to pages
        for (ni = 0; ni < btree->m_min_keys; ++ni)
        {
            insert_info->m_page->m_keys[ni] = temp_keys[ni];
            insert_info->m_page->m_data[ni] = temp_data[ni];

            ++insert_info->m_page->m_key_count;
        }

        for (ni = btree->m_min_keys + 1; ni <= btree->m_order; ++ni)
        {
            page_sibling->m_keys[ni - 1 - btree->m_min_keys] = temp_keys[ni];
            page_sibling->m_data[ni - 1 - btree->m_min_keys] = temp_data[ni];

            ++page_sibling->m_key_count;
        }

        // replace remaining entries with null
        for (ni = btree->m_min_keys; ni < btree->m_order; ++ni)
        {
            insert_info->m_page->m_keys[ni] = NULL_KEY;
            insert_info->m_page->m_data[ni] = NULL_DATA;
        }

        // promote key and its pointer
        if (insert_info->m_page->m_parent == NULL)
        {
            // creating a new root page
            promote_root(btree,
                         temp_keys[btree->m_min_keys],
                         temp_data[btree->m_min_keys],
                         insert_info->m_page,
                         page_sibling);
        }
        else
        {
            // read parent
            btree_page * page_parent = insert_info->m_page->m_parent;
            
            // promote key into parent page
            promote_internal(btree,
                             page_parent,
                             temp_keys[btree->m_min_keys],
                             temp_data[btree->m_min_keys],
                             page_sibling);
        }
        
        // release sibling page
        free(temp_keys);
        free(temp_data);
    }
    else
    {
        // move keys to make room for new one
        for (int n = insert_info->m_page->m_key_count; n > insert_info->m_index; --n)
        {
            insert_info->m_page->m_keys[n] = insert_info->m_page->m_keys[n - 1];
            insert_info->m_page->m_data[n] = insert_info->m_page->m_data[n - 1];
        }

        insert_info->m_page->m_keys[insert_info->m_index] = key;
        insert_info->m_page->m_data[insert_info->m_index] = datum;

        ++insert_info->m_page->m_key_count;
    }
}
Beispiel #3
0
// promote key into parent
static void promote_internal(btree * btree,
                             btree_page * page_insert,
                             btree_key_t  key,
                             btree_data_t datum,
                             btree_page * link)
{
    if (page_insert->m_key_count == btree->m_order)
    {
        // temporary array
        btree_key_t * temp_keys        = (btree_key_t *)malloc(sizeof(btree_key_t) * (btree->m_order + 1));
        btree_data_t * temp_data       = (btree_data_t *)malloc(sizeof(btree_data_t) * (btree->m_order + 1));
        btree_page ** temp_links = (btree_page **)malloc(sizeof(btree_page *) * (btree->m_order + 2));

        temp_links[0] = page_insert->m_links[0];

        // copy entries from inapage to temps
        int nt  = 0;
        int ni  = 0;
        int insert_index = 0;

        // find insertion point
        while ((insert_index < page_insert->m_key_count) && (page_insert->m_keys[insert_index] < key))
            ++insert_index;

        // store new info
        temp_keys[insert_index]      = key;
        temp_data[insert_index]      = datum;
        temp_links[insert_index + 1] = link;

        // copy existing keys
        while (ni < btree->m_order)
        {
            if (ni == insert_index)
                ++nt;

            temp_keys[nt]      = page_insert->m_keys[ni];
            temp_data[nt]      = page_insert->m_data[ni];
            temp_links[nt + 1] = page_insert->m_links[ni + 1];

            ++ni;
            ++nt;
        }

        // generate a new leaf node
        btree_page * page_sibling = alloc_page(btree);
        page_sibling->m_parent = page_insert->m_parent;

        // clear key counts
        page_insert->m_key_count  = 0;
        page_sibling->m_key_count = 0;

        page_insert->m_links[0] = temp_links[0];

        // copy keys from temp to pages
        for (ni = 0; ni < btree->m_min_keys; ++ni)
        {
            page_insert->m_keys[ni]      = temp_keys[ni];
            page_insert->m_data[ni]      = temp_data[ni];
            page_insert->m_links[ni + 1] = temp_links[ni + 1];

            ++page_insert->m_key_count;
        }

        page_sibling->m_links[0] = temp_links[btree->m_min_keys + 1];

        for (ni = btree->m_min_keys + 1; ni <= btree->m_order; ++ni)
        {
            page_sibling->m_keys[ni - 1 - btree->m_min_keys] = temp_keys[ni];
            page_sibling->m_data[ni - 1 - btree->m_min_keys] = temp_data[ni];
            page_sibling->m_links[ni - btree->m_min_keys]    = temp_links[ni + 1];

            ++page_sibling->m_key_count;
        }

        // replace unused entries with null
        for (ni = btree->m_min_keys; ni < btree->m_order; ++ni)
        {
            page_insert->m_keys[ni]      = NULL_KEY;
            page_insert->m_data[ni]      = NULL_DATA;
            page_insert->m_links[ni + 1] = NULL;
        }

        // update parent links in child nodes
        for (ni = 0; ni <= page_sibling->m_key_count; ++ni)
        {
            btree_page * child = page_sibling->m_links[ni];
            child->m_parent = page_sibling;
        }

        // promote key and pointer
        if (page_insert->m_parent == NULL)
        {
            // create a new root
            promote_root(btree,
                         temp_keys[btree->m_min_keys],
                         temp_data[btree->m_min_keys],
                         page_insert,
                         page_sibling);
        }
        else
        {
            // read parent and promote key
            btree_page * parent_page = page_insert->m_parent;

            promote_internal(btree,
                             parent_page,
                             temp_keys[btree->m_min_keys],
                             temp_data[btree->m_min_keys],
                             page_sibling);
        }

        // release resources
        free(temp_keys);
        free(temp_data);
        free(temp_links);
    }
    else
    {
        int insert_index = 0;

        // find insertion point
        while ((insert_index < page_insert->m_key_count) && (page_insert->m_keys[insert_index] < key))
            ++insert_index;

        // shift keys right
        for (int n = page_insert->m_key_count; n > insert_index; --n)
        {
            page_insert->m_keys[n]      = page_insert->m_keys[n - 1];
            page_insert->m_data[n]      = page_insert->m_data[n - 1];
            page_insert->m_links[n + 1] = page_insert->m_links[n];
        }

        page_insert->m_keys[insert_index]      = key;
        page_insert->m_data[insert_index]      = datum;
        page_insert->m_links[insert_index + 1] = link;

        ++page_insert->m_key_count;
    }
}