예제 #1
0
/*
 * 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);
}
예제 #2
0
/*!
 * 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;
	}

}