int insertR(int key, Node r_child_of_key, Node node, stack path_stack, int tid) { if (node->is_leaf) { // set the $thread_on bit to indicate thread $tid is entering. pthread_mutex_lock(&node->mutex); node->thread_on |= 0x01 << tid; pthread_mutex_unlock(&node->mutex); while (node->reorganize_bit & 0x01) { //pthread_mutex_lock(&node->mutex); //can u get this lock??? //pthread_cond_wait(&node->is_under_reorganizing, &node->mutex); //pthread_mutex_unlock(&node->mutex); } // check its own region capacity; not full is safe, and release locks // of ancestors, including parent. if (node->private_region_capacity[tid] != 0) { while (!path_stack->is_empty(path_stack)) { pthread_mutex_unlock(&((Node) path_stack->top(path_stack)->data)->mutex); path_stack->pop(path_stack); } } // search in organized region (linear) int i; for (i = 0; i < node->organized_keys; ++i) { if (key == node->keys[i]) return 0; else if (key < node->keys[i]) break; } // key is between [i - 1] and [i]; follow child[i] // if it is leaf, linear search in private region (in leaf); or insert. // path_stack only contains from root to the parent of this $node. // insert the key record when $capacity != 0 if (node->private_region_capacity[tid] != 0) { int insert_position = node->private_region_index[tid] + node->private_region_keys[tid]; node->keys[insert_position] = key; //node->values[insert_position] = val; node->private_region_keys[tid] += 1; // if two threads meet the same situation and wait for each other to // complete the reorganization... $reorganize_bit $thread_on??? // how to deal with them in here. if (node->private_region_capacity[tid] == node->private_region_keys[tid]) { pthread_mutex_lock(&node->mutex); if (!(node->reorganize_bit & 0x01) && (node->private_region_capacity[tid] == node->private_region_keys[tid]) && (node->private_region_capacity[tid] != 0)) { node->reorganize_bit |= 0x01; reorganize(node); node->reorganize_bit &= 0x00; //pthread_cond_broadcast(&node->is_under_reorganizing); } pthread_mutex_unlock(&node->mutex); } } else { // split the $node //TODO: // check whether other threads are manipulating the node by // using the $thread_on in each node. And wait to lock the node. pthread_mutex_lock(&node->mutex); while (node->thread_on ^ (0x01 << tid)) { //!!!careful: if it needs to reset the $thread_on // and set it after condition wait. node->thread_on ^= 0x01 << tid; //!? right or wrong? pthread_cond_wait(&node->is_going_splitting, &node->mutex); node->thread_on |= 0x01 << tid; //!? right or wrong? } // start to split; reorganize first node->reorganize_bit |= 0x01; reorganize(node); node->reorganize_bit &= 0x00; Node u = node; Node v = createNode(1); // 1 => is leaf; Node r_subtree = r_child_of_key; int median = splitLeaf(u, v); int elem = key; int finish = 0; if (u == root) { root = createNode(0); root->keys[0] = median; root->organized_keys++; root->child[0] = u; root->child[1] = v; finish = 1; } else { elem = median; r_subtree = v; u = (Node) path_stack->top(path_stack)->data; path_stack->pop(path_stack); } pthread_mutex_unlock(&node->mutex); while (/*!path_stack->is_empty() && */!finish) { if (u->organized_keys < (order - 1)) { insertElem(elem, r_subtree, u); finish = 1; } else { v = createNode(0); median = splitNonleaf(elem, r_subtree, u, v); if (u == root) { root = createNode(0); root->keys[0] = median; root->organized_keys++; root->child[0] = u; root->child[1] = v; finish = 1; } else { pthread_mutex_unlock(&u->mutex); elem = median; r_subtree = v; u = (Node) path_stack->top(path_stack)->data; path_stack->pop(path_stack); } } } pthread_mutex_unlock(&u->mutex); } pthread_mutex_lock(&node->mutex); node->thread_on ^= 0x01 << tid; pthread_cond_signal(&node->is_going_splitting); pthread_mutex_unlock(&node->mutex); } else { // lock this node, and follow child[i] pthread_mutex_lock(&node->mutex); // if current node is safe, then release all ancestors. if (node->organized_keys < (order - 1)) { while (!path_stack->is_empty()) { pthread_mutex_unlock(&((Node) path_stack->top(path_stack)->data)->mutex); path_stack->pop(path_stack); } } // search in organized region (linear) int i; for (i = 0; i < node->organized_keys; ++i) { if (key == node->keys[i]) return 0; else if (key < node->keys[i]) break; } // key is between [i - 1] and [i]; follow child[i] struct stack_node_struct stack_node; stack_node.data = node; path_stack->push(path_stack, &stack_node); insertR(key, r_child_of_key, node->child[i], path_stack); } }