// Syfte: Anvands for att ta bort element i tabellen. // Genom att frigora minnesallokeringen for key // och flyttar det sista elementet till den tomma // positionen. Haller aven reda pa hur manga element // som finns i tabellen. // Inparametrar: Pekare till en tabell och pekare till en nyckel. // Returnerar: Ingenting. void table_remove(Table *table, KEY key) { ArrayTable *t = (ArrayTable*)table; TableElement *i = calloc(1,sizeof(TableElement)); int position; // loopar ingenom arrayen till slutet av listan. Avbryter // om slutet av listan dvs. NULL eller om vardet aterfinns. // Om vardet aterfinns sa returneras detta. for (position=0;array_hasValue(t->values,position);position++) { i = array_inspectValue(t->values,position); if (t->cf(i->key,key)==0) { // Flytta sista vardet till platsen for det borttagna vardet. // Har refererar t->count-1 till en intexering. array_setValue(t->values, array_inspectValue(t->values,t->count-1), position); // Frigor minne for key och value pa den gamla positionen. if(t->keyFree!=NULL) t->keyFree(i->key); if(t->valueFree!=NULL) t->valueFree(i->value); // Ersatter den gamla positionen med NULL. // Har refererar t->count-1 inte som count utan som en indexering. array_setValue(t->values, NULL, t->count-1); t->count--; // Raknar ner count efter allt gjorts. * break; } } }
// Syfte: Att aterge vardet for en specifik nyckel. // Inparametrar: Pekare till en tabell och pekare till nyckel. // Returnerar: NULL om elementet saknas. Vardet om det aterfinns. VALUE table_lookup(Table *table, KEY key) { ArrayTable *t = (ArrayTable*)table; TableElement *i = calloc(1,sizeof(TableElement)); int position; // Lopar igenom arrayen tills dess att compare_function // har hittat vardet. Om null avbryts lopen och NULL returneras. // Om compare_function hittar igen vardet returneras detta. for (position=0;array_hasValue(t->values,position);position++){ i=array_inspectValue(t->values,position); if (t->cf(i->key,key)==0) return i->value; } return NULL; }
/* Inserts a key and value pair into the table. If memhandlers are set the table takes * ownership of the key and value pointers and is responsible for * deallocating them when they are removed. * table - Pointer to the table. * key - Pointer to the key. * value - Pointer to the value. */ void table_insert(Table *table, KEY key, VALUE value){ ArrayTable *t = (ArrayTable*)table; // make a new table element TableElement *e=malloc(sizeof(TableElement)); e->key = key; e->value = value; // table element to work on TableElement *i; // get loop boundaries for array // array_high and array_low return // arrays array *aHigh = array_high(t->values); array *aLow = array_low(t->values); int high = *((int*)array_inspectValue(aHigh,0)); int low = *((int*)array_inspectValue(aLow,0)); array_free(aHigh); array_free(aLow); // travers through the table/array until either the same key found // or an empty space found // Current, If the table is full, new element is not inserted! for ( int pos = low; pos < high; pos++){ // get TableElement of current array pos i = array_inspectValue(t->values,pos); // if current array pos is empty, put in new element and break if(i == NULL){ array_setValue(t->values,e,pos); t->elementCounter++; break; } // if the key of the current table element is the same as the new // put the new element in place of the old and break if (t->cf(i->key,key)==0){ array_setValue(t->values,e,pos); break; } } }
/* Removes an item from the table given its key. * table - Pointer to the table. * key - Pointer to the item's key. */ void table_remove(Table *table, KEY key){ ArrayTable *t = (ArrayTable*)table; // table element to work on TableElement *i; // get loop boundaries for array // array_high and array_low return // arrays array *aHigh = array_high(t->values); array *aLow = array_low(t->values); int high = *((int*)array_inspectValue(aHigh,0)); int low = *((int*)array_inspectValue(aLow,0)); array_free(aHigh); array_free(aLow); // loop through the table/array until all keys found // or all positions visited for ( int pos = low; pos < high; pos++){ // get TableElement of current array pos i = array_inspectValue(t->values,pos); // if current array pos is empty, skip to next if(i == NULL){ continue; } // if the key of the current table element is the same as the one // one to remove, set to NULL and go on if (t->cf(i->key,key)==0){ array_setValue(t->values, NULL, pos); t->elementCounter--; } } }
/* Finds a value given its key. * table - Pointer to the table. * key - Pointer to the item's key. * Returns: Pointer to the item's value if the lookup succeded. NULL if the * lookup failed. The pointer is owned by the table type, and the * user should not attempt to deallocate it. It will remain valid * until the item is removed from the table, or the table is * destroyed. */ VALUE table_lookup(Table *table, KEY key){ ArrayTable *t = (ArrayTable*)table; // get loop boundaries for array // array_high and array_low return // arrays array *aHigh = array_high(t->values); array *aLow = array_low(t->values); int high = *((int*)array_inspectValue(aHigh,0)); int low = *((int*)array_inspectValue(aLow,0)); array_free(aHigh); array_free(aLow); // table element to work on TableElement *i; // loop through the table/array until the same key found // or end of array reached for ( int pos = low; pos < high; pos++) { // get TableElement of current array pos i = array_inspectValue(t->values, pos); // if current array pos is empty, put in new element and break if (i == NULL) { continue; } // if the key of the current table element is the same as the // lookup key, return the value if (t->cf(i->key, key) == 0) { return i->value; } } return NULL; }
// Syfte: Lagger till ett element i arrayen. Darmed bade ett varde, // value, och en nyckel, key. Haller aven reda pa hur // manga element som finns i arrayen. // Inparametrar: Pekare till tabellen, pekare till nyckel, pekare till vardet. // Returnerar: Returnerar inget. void table_insert(Table *table, KEY key,VALUE value) { ArrayTable *t = (ArrayTable*)table; TableElement *i = malloc(sizeof(TableElement)); TableElement *replaceElement = malloc(sizeof(TableElement)); i->key = key; i->value = value; int setNewValue = true; int position; // For att behalla unika nycklar. // For varje element som har ett varde... for (position=0;array_hasValue(t->values,position);position++) { // ...kolla om nyckeln ar den samma. // Om samma, byt ut vardet med samma nyckel. replaceElement = array_inspectValue(t->values,position); if (t->cf(replaceElement->key,key)==0) { // Frigor minne for tidigare nyckel for tidigare element. if(t->keyFree!=NULL) t->keyFree(i->key); if(t->valueFree!=NULL) t->valueFree(i->value); replaceElement->value = value; // Satt det nya vardet pa plats. array_setValue(t->values,replaceElement,position); // Behover inte satta in ett nytt element med samma nyckel. setNewValue = false; // Eftersom ingenting flyttas behover count inte forandras. } } // Om ingen likadan nyckel finns // Satt in elementet i arrayen. Nyckel och varde. if (setNewValue) { array_setValue(t->values,i,t->count); // Rakna upp count for varje instoppat t->count++; } }