// 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: Hämta de lägsta möjliga index som är giltiga för arrayen. Parametrar: arr - arrayen. Returvärde: Endimensionell array med ett värde per dimension i arrayen som man vill kontrolera de giltiga indexen för. Arrayen innehåller int-pekare. low för den returnerade arrayen är 0 och high antalet dimensioner-1. Kommentarer: Användaren av funktionen är ansvarig för att avallokera minnet för den returnerade arrayen. Minne för värdena i den returnerade arrayen får ej avallokeras. Datavärdena i den returnerade arrayen är endast tillgängliga så länge som man ej avallokerat minnet för den ursprungliga arrayen. */ array * array_low(array * arr) { array *lowIndex=array_create(1,0,arr->numDimensions-1); for(int i=0;i<arr->numDimensions;i++) { array_setValue(lowIndex,&(arr->low[i]),i); } return lowIndex; }
/* Syfte: Hämta de högsta möjliga index som är giltiga för arrayen. Parametrar: arr - arrayen. Returvärde: Endimensionell array med ett värde per dimension i arrayen som man vill kontrolera de giltiga indexen för. Arrayen innehåller int-pekare. low för den returnerade arrayen är 0 och high antalet dimensioner-1. Kommentarer: Användaren av funktionen är ansvarig för att avallokera minnet för den returnerade arrayen. Minne för värdena i den returnerade arrayen får ej avallokeras. Datavärdena i den returnerade arrayen är endast tillgängliga så länge som man ej avallokerat minnet för den ursprungliga arrayen. */ array * array_high(array * arr) { array *highIndex=array_create(1,0,arr->numDimensions-1); for(int i=0;i<arr->numDimensions;i++) { array_setValue(highIndex,&(arr->high[i]),i); } return highIndex; }
/* 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; } } }
// 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++; } }
// Syfte: Skapar en ArrayTable. // compare_function: // Pekare till en funktion som anvands for att jamfora // tva nycklar. Funktionen kommer returnera <0 om den // vanstra parametern ar mindre an den hogra parametern, // 0 om parametern ar samma och >0 om den vanstra // parametern ar storre an det hogra elementet. // Returnerar: En pekare till en tabell. // NULL om skapandet av tabellen misslyckats. Table *table_create(CompareFunction *compare_function) { ArrayTable *t = calloc(1,sizeof (ArrayTable)); if (!t) return NULL; t->values=array_create(1,0,MAX_NUM_OF_ELEMENTS-1); t->count = 0; t->cf = compare_function; int position; for (position=0;position<MAX_NUM_OF_ELEMENTS;position++){ array_setValue(t->values, NULL,position); } return t; }
/* 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--; } } }