/* * Adds or updates a user: * * - If a user with the name userName exists, its 'number of contacts' count * will be incremented. * - If the user doesn't exist, the user will be added to the table, and its * number of contacts' count set to 1. */ void updateUser(char *userName) { int userIndex; aorToIndexStruct_t *newRecord; aorToIndexStruct_t *existingRecord = findHashRecord(hashTable, userName, HASH_SIZE); /* We found an existing record, so we need to update its 'number of * contacts' count. */ if (existingRecord != NULL) { existingRecord->numContacts++; return; } /* Make a new row, and insert a record of it into our mapping data * structures */ userIndex = createRegUserRow(userName); if (userIndex == 0) { LM_ERR("openserSIPRegUserTable ran out of memory." " Not able to add user: %s", userName); return; } newRecord = createHashRecord(userIndex, userName); /* If we couldn't create a record in the hash table, then we won't be * able to access this row properly later. So remove the row from the * table and fail. */ if (newRecord == NULL) { deleteRegUserRow(userIndex); LM_ERR("openserSIPRegUserTable was not able to push %s into the hash." " User not added to this table\n", userName); return; } /* Insert the new record of the mapping data structure into the hash * table */ /*insertHashRecord(hashTable, createHashRecord(userIndex, userName), HASH_SIZE);*/ insertHashRecord(hashTable, newRecord, HASH_SIZE); }
/*! * This function will search the provided hash table for an entry indexed by * 'aor'. If an entry is found then: * * - Its numContacts counter will be decremented. * - If its numContacts counter reaches zero, then the entry will be removed * from the hash table. * */ void deleteUser(hashSlot_t *theTable, char *aor, int hashTableSize) { int hashIndex = calculateHashSlot(aor, hashTableSize); int searchStringLength = strlen(aor); aorToIndexStruct_t *previousRecord = theTable[hashIndex].first; aorToIndexStruct_t *currentRecord = theTable[hashIndex].first; while (currentRecord != NULL) { /* First make sure both strings are the same length. If so, * then compare all bytes. If this succeeds, then we need to * link up the previous and next element together. */ if (currentRecord->aorLength == searchStringLength && memcmp(currentRecord->aor, aor, searchStringLength) == 0) { currentRecord->numContacts--; /* There are still contacts relying on this user, so * don't delete anything. */ if (currentRecord->numContacts > 0) { return; } /* There are no more contacts relying on this user, so * delete the row from the table. */ deleteRegUserRow(currentRecord->userIndex); /* Maintenance of the hash table */ if (currentRecord->prev == NULL) { /* Edge Case: First element in list was just deleted, so set * up the first element to point to the one after the one * just deleted */ theTable[hashIndex].first = currentRecord->next; } else { /* Not the first element, so hook up the previous node to * the node after the one just deleted. */ currentRecord->prev->next = currentRecord->next; } if (currentRecord->next == NULL) { /* Edge Case: The last element has been targetted for * deletion. So move the pointer to the node just before * this one. */ theTable[hashIndex].last = currentRecord->prev; } else { /* Not the last element, so hook up next nodes previous * element to this nodes previous. */ currentRecord->next->prev = currentRecord->prev; } pkg_free(currentRecord); /* We are done, so just return. */ return; } /* Advance to the next records. */ previousRecord = currentRecord; currentRecord = currentRecord->next; } }