Пример #1
0
// 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;
        }
    }
}
Пример #2
0
/* Destroys a table, deallocating all the memory it uses.
 *  table - Pointer to the table. After the function completes this pointer
 *          will be invalid for further use. */
void table_free(Table *table){
    ArrayTable *t = (ArrayTable*)table;
    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);

    // traversing through the array and freeing
    // memory for table elements if the memory handler
    // was set
    for (int pos = low; pos < high; pos++){
        i = array_inspectValue(t->values, pos);

        if(array_hasValue(t->values, pos)){
            if(t->keyFree!=NULL) {
                t->keyFree(i->key);
            }
            if(t->valueFree!=NULL) {
                t->valueFree(i->value);
            }
        }
    }

    // freeing memory for the array and the table struct
    array_free(t->values);
    free(t);
}
Пример #3
0
/* 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;
        }


    }
}
Пример #4
0
/* 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--;
        }

    }


}
Пример #5
0
/* 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;
}
Пример #6
0
// 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;
}
Пример #7
0
// Syfte:        Funktionen tar bort tabellen och frigor minne.
// Inparametrar: Pekare till en tabell.
// Returnerar:   Ingenting.
void table_free(Table *table) {
    ArrayTable *t = (ArrayTable*)table;
    TableElement *i = calloc(1,sizeof(TableElement));
    int position;

    // Loopar genom hela arrayen for att ta bort minne.
    // Avslutas nar vi natt slutet, dvs NULL.
    // Tar bort minnesallokering for nycklar, keys, och
    // minnesallokering for varden, value.
    for (position=0;array_hasValue(t->values,position);position++) {
        i=array_inspectValue(t->values,position);
        if(t->keyFree!=NULL)
            t->keyFree(i->key);
        if(t->valueFree!=NULL)
            t->valueFree(i->value);
        table_remove(t,i->key);
    }
    array_free(t->values);
    // Frigor slutligen allokerat minne for tabellen.
    free(t);
}
Пример #8
0
// 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++;
    }
}