Beispiel #1
0
struct rb_node *RBTreeSearch(struct rb_tree *rb, rb_key_t key) {     //same as Binary Search Tree's search operation
	struct rb_node *x = rb->root;
	while (x != rb->nil) {
		if (keyCmp(x->key, key) > 0)
			x = x->left;
		else if (keyCmp(x->key, key) < 0)
			x = x->right;
		else
			break;
	}
	return x;
}
Beispiel #2
0
apiRetVal
hashMapOpen::remove (hashNodeKey *key, void **data)
{
    uint32_t hashKey;
    hashNode *node = NULL, *prevNode = NULL;

    hashKey = getHashKey(key);
    if (hashKey > tableLength) {
        return API_RETVAL_INVALID_INPUT;
    }
    node = hashTable[hashKey];

    while (node) {
        if (keyCmp(key, &node->nodeKey)) {
            *data = node->data;
            if (!prevNode) {
                // This is the first node.
                hashTable[hashKey] = node->next;
            } else {
                prevNode->next = node->next;
            }
            free(node);
            return (API_RETVAL_SUCCESS);
        }
        prevNode = node;
        node = node->next;
    }
    return API_RETVAL_DATA_NOT_FOUND;
}
Beispiel #3
0
Index fileGetIndex(struct Container * container, struct Key * pk)
{   
    int readBufferSize = 1;
    const int sizeOfRecord = sizeof(struct Record);
    const int sizeOfHeader = sizeof(struct Header);
    struct Record rec; unsigned int index=0;
    int readedValue;

    printf("iterating records: %i\n", container->records);
    for (; index < container->records; ++index)
    {
        int seekTo = sizeOfHeader+sizeOfRecord*index;
        fseek(container->storage->base[FILE_BASE_IND]->handle, seekTo, SEEK_SET);
        printf("seekTo %i, ind:%i\n", seekTo, index);
        readedValue = fread(&rec, sizeof(struct Record), readBufferSize, container->storage->base[FILE_BASE_IND]->handle); //mmap/read might be better
        
        if (keyCmp(&rec.key, pk))
		{
            printf("found pk match\n");
            break;
        }
    }
    
    if (readedValue)
    {
        printf("rec->pk:%u, index:%u\n", pk->pk, index);
    }
    return index;
}
Beispiel #4
0
/*
 * Wrapper for the function comparing by order metadata. As
 * qsort is not stable returning 0 on missing order may
 * mess up the original order.
 */
int elektraKeyCmpOrderWrapper (const void * a, const void * b)
{
    const Key ** ka = (const Key **)a;
    const Key ** kb = (const Key **)b;

    int orderResult = elektraKeyCmpOrder (*ka, *kb);

    /* comparing the order meta could not order the keys
     * revert to comparing the names instead
     */
    if (orderResult == 0) return keyCmp (*ka, *kb);

    return orderResult;
}
Beispiel #5
0
/**
 * Information about the relation in the hierarchy between
 * two keys.
 *
 * Unlike keyCmp() the number gives information
 * about hierarchical information.
 *
 *
 * - If the keys are the same 0 is returned.
 * So it is the key itself.
 @verbatim
 user/key
 user/key
 @endverbatim
 *
 *@code
 keySetName (key, "user/key/folder");
 keySetName (check, "user/key/folder");
 succeed_if (keyRel (key, check) == 0, "should be same");
 *@endcode
 *
 * @note this relation can be checked with keyCmp() too.
 *
 *
 * - If the key is direct below the other one 1 is returned.
 * That means that, in terms of hierarchy, no other key is
 * between them - it is a direct child.
 @verbatim
 user/key/folder
 user/key/folder/child
 @endverbatim
 *
 *@code
 keySetName (key, "user/key/folder");
 keySetName (check, "user/key/folder/child");
 succeed_if (keyRel (key, check) == 1, "should be direct below");
 *@endcode
 *
 *
 * - If the key is below the other one, but not directly 2 is returned.
 * This is also called grand-child.
 @verbatim
 user/key/folder
 user/key/folder/any/depth/deeper/grand-child
 @endverbatim
 *
 *
 *@code
 keySetName (key, "user/key/folder");
 keySetName (check, "user/key/folder/any/depth/deeper/grand-child");
 succeed_if (keyRel (key, check) >= 2, "should be below (but not direct)");
 succeed_if (keyRel (key, check) > 0, "should be below");
 succeed_if (keyRel (key, check) >= 0, "should be the same or below");
 *@endcode
 *
 *
 * - If a invalid or null ptr key is passed, -1 is returned
 *
 *
 * - If the keys have no relations, but are not invalid, -2 is returned.
 *
 *
 * - If the keys are in the same hierarchy, a value smaller then -2 is returned.
 * It means that the key is not below.
 @verbatim
 user/key/myself
 user/key/sibling
 @endverbatim
 *
 * @code
 keySetName (key, "user/key/folder");
 keySetName (check, "user/notsame/folder");
 succeed_if (keyRel (key, check) < -2, "key is not below, but same namespace");
 * @endcode
 *
 * @code
 * @endcode
 *
 *
 * TODO Below is an idea how it could be extended:
 * It could continue the search into the other direction
 * if any (grand-)parents are equal.
 *
 * - If the keys are direct below a key which is next to the key, -2 is returned.
 * This is also called nephew. (TODO not implemented)
 * @verbatim
 user/key/myself
 user/key/sibling
 @endverbatim
 *
 * - If the keys are direct below a key which is next to the key, -2 is returned.
 * This is also called nephew. (TODO not implemented)
 * @verbatim
 user/key/myself
 user/key/sibling/nephew
 @endverbatim
 *
 * - If the keys are below a key which is next to the key, -3 is returned.
 * This is also called grand-nephew. (TODO not implemented)
 @verbatim
 user/key/myself
 user/key/sibling/any/depth/deeper/grand-nephew
 @endverbatim
 *
 * The same holds true for the other direction, but with negative values.
 * For no relation INT_MIN is returned.
 *
 * @note to check if the keys are the same, you must use
 *		keyCmp() == 0!
 *		keyRel() does not give you the information if it did not
 *		find a relation or if it is the same key.
 *
 * @return depending on the relation
 * @retval 2 if below
 * @retval 1 if direct below
 * @retval 0 if the same
 * @retval -1 on null or invalid keys
 * @retval -2 if none of any other relation
 * @retval -3 if same hierarchy (none of those below)
 * @retval -4 if sibling (in same hierarchy)
 * @retval -5 if nephew (in same hierarchy)
 *
 * @param key the key object to work with
 * @param check the second key object to check the relation with
 * @ingroup keytest
 */
int keyRel (const Key * key, const Key * check)
{
	if (!key || !check) return -1;
	if (!key->key || !check->key) return -1;

	if (!keyCmp (key, check)) return 0;
	if (keyIsDirectBelow (key, check)) return 1;
	if (keyIsBelow (key, check)) return 2;
	if (keyIsUser (key) && keyIsUser (check)) return -3;
	if (keyIsSystem (key) && keyIsSystem (check)) return -3;
	// if (keyIsSibling(key, check)) return -4;
	// if (keyIsNephew(key, check)) return -5;

	return -2;
}
Beispiel #6
0
void RBTreeInsert(struct rb_tree *rb, rb_key_t key) {
	struct rb_node *z = createRBNode(key, RED);
	struct rb_node *x, *y;
	rb->size++;
	y = rb->nil;
	x = rb->root;
	while (x != rb->nil) {
		y = x;
		if (keyCmp(x->key, key) > 0) 
			x = x->left;
		else
			x = x->right;
	}
	z->p = y;
	if (y == rb->nil)
		rb->root = z;
	else if (keyCmp(y->key, key) > 0)
		y->left = z;
	else
		y->right = z;
	z->left = rb->nil;
	z->right = rb->nil;
	RBTreeInsertFixup(rb, z);
}
Beispiel #7
0
static void test_lookupNoascading ()
{
	printf ("Test lookup without cascading\n");

	Key * specKey = keyNew ("/abc", KEY_CASCADING_NAME, KEY_END);

	Key * d = keyDup (specKey);
	keySetString (d, "dup");
	succeed_if_same_string (keyName (specKey), "/abc");
	succeed_if_same_string (keyName (d), "/abc");

	succeed_if (!keyCmp (d, specKey), "comparision to duplicate failed");
	succeed_if_same_string (keyName (d), "/abc");
	succeed_if_same_string (keyName (specKey), "/abc");

	KeySet * ks = ksNew (20, d, KS_END);

	Key * k = ksLookup (ks, specKey, KDB_O_NOCASCADING);
	succeed_if_same_string (keyName (specKey), "/abc");
	succeed_if (k != 0, "did not find cascading key");
	succeed_if (k != specKey, "should not be specKey");
	succeed_if (k == d, "should be dup key");

	Key * a = keyNew (keyName (specKey), KEY_CASCADING_NAME, KEY_VALUE, "a", KEY_END);
	ksAppendKey (ks, a);

	for (int i = 0; i < 5; ++i)
	{
		k = ksLookup (ks, specKey, KDB_O_NOCASCADING);
		succeed_if (keyGetNameSize (specKey) == 5, "size of spec key wrong");
		succeed_if_same_string (keyName (specKey), "/abc");
		succeed_if (k != 0, "did not find cascading key");
		succeed_if (k != specKey, "should not be specKey");
		succeed_if (k == a, "should be dup key");

		// search without cascading
		k = ksLookup (ks, specKey, 0);
		succeed_if (keyGetNameSize (specKey) == 5, "size of spec key wrong");
		succeed_if_same_string (keyName (specKey), "/abc");
		succeed_if (k != 0, "did not find cascading key");
		succeed_if (k != specKey, "should not be specKey");
		succeed_if (k == a, "should be dup key");
	}

	ksDel (ks);
	keyDel (specKey);
}
static CondResult evalMultipleConditions (Key * key, const Key * meta, const Key * suffixList, Key * parentKey, KeySet * returned)
{
	int countSucceeded = 0;
	int countFailed = 0;
	int countNoexpr = 0;
	KeySet * condKS = elektraMetaArrayToKS (key, keyName (meta));
	Key * c;
	CondResult result = FALSE;
	while ((c = ksNext (condKS)) != NULL)
	{
		if (!keyCmp (c, meta)) continue;
		result = evaluateKey (c, suffixList, parentKey, key, returned, CONDITION);
		if (result == TRUE)
			++countSucceeded;
		else if (result == ERROR)
			++countFailed;
		else if (result == NOEXPR)
			++countNoexpr;
	}
	ksDel (condKS);
	if (!strcmp (keyBaseName (meta), "all"))
	{
		// all conditions must evaluate to TRUE
		if (countFailed || countNoexpr)
			return ERROR;
		else
			return TRUE;
	}
	else if (!strcmp (keyBaseName (meta), "any"))
	{
		// at least one conditional must evaluate to TRUE
		if (countSucceeded)
			return TRUE;
		else
			return ERROR;
	}
	else
	{
		// no condition must evaluate to FALSE
		if (countFailed)
			return ERROR;
		else
			return TRUE;
	}
}
Beispiel #9
0
static void flushConvertedKeys (Key * target, KeySet * converted, KeySet * orig)
{
    if (ksGetSize (converted) == 0) return;

    ksRewind (converted);
    Key * current;
    Key * appendTarget;

    while ((current = ksNext (converted)))
    {
        appendTarget = target;
        const char * metaName = keyString (keyGetMeta (current, CONVERT_METANAME));

        Key * currentDup = keyDup (current);
        Key * targetDup = keyDup (appendTarget);
        keySetBaseName (currentDup, 0);
        keySetBaseName (targetDup, 0);

        /* the convert key request to be converted to a key
         * on the same level, but the target is below or above
         */
        if (keyGetMeta (current, CONVERT_APPEND_SAMELEVEL) && keyCmp (currentDup, targetDup))
        {
            appendTarget = 0;
        }

        keyDel (currentDup);
        keyDel (targetDup);

        /* no target key was found of the target
         * was discarded for some reason. Revert to the parent
         */
        if (!appendTarget)
        {
            appendTarget = findNearestParent (current, orig);
        }

        elektraKeyAppendMetaLine (appendTarget, metaName, keyString (current));
        removeKeyFromResult (current, target, orig);
    }

    ksClear (converted);
}
Beispiel #10
0
apiRetVal
hashMapOpen::find (hashNodeKey *key, void **data)
{
    uint32_t hashKey;
    hashNode *node = NULL;

    hashKey = getHashKey(key);
    if (hashKey > tableLength) {
        return API_RETVAL_INVALID_INPUT;
    }

    node = hashTable[hashKey];
    while (node) {
        if (keyCmp(key, &node->nodeKey)) {
            *data = node->data;
            return (API_RETVAL_SUCCESS);
        }
        node = node->next;
    }
    return API_RETVAL_DATA_NOT_FOUND;
}