int Repository_update(int key, int data) { // A variable the loops through the list element *temp_pointer; // A variable that will hold the new element in the list element *pelement; // When adding a new variable, will hold what level the variable was added to int curr_level = 0; // Temp variable to use with the pop() function int r; // Will hold a pointer to the val of the very bottom row since there should only be // one copy of data per column in the skip list int *val_ptr; // Holds a pointer down so each subsequent layer in the skip list point to the element below it element *down_ptr; // Initializes the looping variable to the very top sentinel node temp_pointer = top_ptr; // This will serve as a sentinel node for the new level element *new_head; // Loops through the list while(temp_pointer!= NULL){ // Loop through each level until the end of the list or a key greater than // the key being searched for is found while(temp_pointer->next != NULL && key >= (temp_pointer->next)->key){ // If the key is found, update its associated value and return 0 if((temp_pointer->next)->key == key){ *((temp_pointer->next)->val) = data; return 0; } // Make temp_pointer equal to the next element in the level temp_pointer = temp_pointer -> next; steps++; } // Hold the value of the element before the one greater than the key in a stack. // If there is not an element with a key hreater than the key being searched for, // the last element in the level is saved. // This can then be used to add the new element to the super list r = push(temp_pointer); if( r == 0) return -1; // Go down one level when a value greater than the one being searched for is found, then // search for a value equal to or greater than the key temp_pointer = temp_pointer->down; steps++; } // This block of code runs if the key is not found in the bottom level r = pop(&temp_pointer); pelement = malloc(sizeof(element)); if( pelement == NULL) return -1; pelement->val = malloc(sizeof(int)); *(pelement->val) = data; // Save a pointer to the value associated with the key val_ptr = pelement->val; pelement->key = key; pelement->down = NULL; // Save a pointer to the element being added. The element on the next row up // can use this pointer down_ptr = pelement; pelement->next = temp_pointer->next; steps++; temp_pointer->next = pelement; steps++; // Increase the size of the bottom level in the array of level sizes size[curr_level]++; // We are now done working with the bottom level, so the curr_level value is iterated curr_level++; // This loop runs while rand100() produces a value greater than the previously specified percent // Every time this is true, an element is added one level up while(rand100() <= percent){ // Runs if the level being added to exists already if(curr_level <= level){ // Set temp_pointer equal to the last saved item // The new element is added after this item r = pop(&temp_pointer); pelement = malloc(sizeof(element)); if( pelement == NULL) return -1; pelement->val = val_ptr; pelement->key = key; pelement->down = down_ptr; steps++; pelement->next = temp_pointer->next; steps++; temp_pointer->next = pelement; steps++; // Pelement will then be the last added element, so the next one should point // down to it down_ptr = pelement; size[curr_level]++; curr_level++; } else{ // Creates space for the new sentinel node new_head = malloc(sizeof(element)); // Creates the new element to be added pelement = malloc(sizeof(element)); pelement->val = val_ptr; pelement->key = key; pelement->down = down_ptr; steps++; pelement->next = NULL; new_head->next = pelement; new_head->val = malloc(sizeof(int)); // Point this sentinel node towards the last sentinel node new_head->down = top_ptr; steps++; // Change top_ptr to point to the new sentinel node top_ptr = new_head; size[curr_level]++; down_ptr = pelement; // Increment this since a new level has been added level++; curr_level++; } } r = 1; // Make sure there is nothing left in the stack at the end of the function while(r != 0) r = pop(&temp_pointer); return 1; }
/*Updates the data if the key is found. If not, insert new record and roll to see how many "layers" needed for this new record*/ int Repository_update(int key, int data) { record *tempList = ListHead; /*tempList is used to traverse data structure*/ record *tempPointer = NULL; /*tempPointer points to the previous inserted record*/ record *temp_record; /*record to be added*/ record *newListHead; /*newListHead is a temp ListHead if we need to create a new lvl*/ record *level_save[levels]; /*level_save is an array of pointers that mark where we stopped on prev lvl*/ int *data_pointer; /*data_pointer creates a pointer to data, so easy to manipulate across all lvls*/ int x = 0; /*x keeps track of where in array to access*/ while(tempList != NULL)/*Checks by level for the record to insert after*/ { while(tempList->next != NULL && tempList->next->key <= key) { if(tempList->next->key == key) { *tempList->next->data = data; return 0; /*data updated*/ } tempList = tempList->next; next_count++; } level_save[x] = tempList;/*stores the record where it stopped and went down*/ x++; tempList = tempList->down; next_count++; record *tempHead2 = ListHead; } /*Now that we have all the points of insertion, add them in*/ /*If we reach this point, it means we need to insert*/ data_pointer = malloc(sizeof(int)); if(data_pointer == NULL) return -1; *data_pointer = data; do { temp_record = malloc(sizeof(record)); if(temp_record == NULL) return -1; temp_record->key = key; temp_record->data = data_pointer; temp_record->down = tempPointer; if(x >= 1) { temp_record->next = level_save[x-1]->next; level_save[x-1]->next = temp_record; level_save[x-1] = NULL; x--; } else if( x < 1)/*Creates new level if probability is "rolled"*/ { temp_record->next = NULL; newListHead = malloc(sizeof(record)); if(newListHead == NULL) return -1; newListHead->down = ListHead; newListHead->next = temp_record; ListHead = newListHead; next_count = next_count + 3; levels++; } tempPointer = temp_record; }while(rand100() <= probability && levels <= MAX_LEVELS); return 1;/*successful insert*/ }