Search code examples
cfileb-treemodularity

Is it possible to modularize C functions with different argument types?


I'm building a bTree to deal with 2 different file types.

struct bNode {
    char nodeType;
    int numKeys;
    Key key[MAX_KEYS+1];
    int desc[MAX_DESC+1];
};

struct bNode2 {
    char nodeType;
    int numKeys;
    Key2 key[MAX_KEYS+1];
    int desc[MAX_DESC+1];
};

Each node has the specified struct as above. I would like to use the same function searchID() on both (instead of creating searchID2() for example).

int searchID(FILE *indexFile, struct bNode *node, int id) {
    if (node->nodeType == LEAF) {
        for (int i = 0; i < node->numKeys; i++)
            if (node->key[i].id == id)
                return node->key[i].rrn;
    } else {
        int i = 0;

        while (i < node->numKeys && id > node->key[i].id)
            i++;
        if (id == node->key[i].id)
            return node->key[i].rrn;

        struct bNode *desc = readNode(indexFile, node->desc[i]);
        return searchID(indexFile, desc, id);
    }
    return -1;
}

Tried to implemented using void * but it didn't work at all.


Solution

  • You can merge the two structs by using an embedded union then using the nodeType as a tag to figure out which of the two keys you are interested for a given instance of the struct:

    struct bNode {
        char nodeType;
        int numKeys;
        union {
           Key key[MAX_KEYS+1];
           Key2 key2[MAX_KEYS+1]; // note: renamed to key2 to not conflict
        };
        int desc[MAX_DESC+1];
    };
    

    Then in your function you switch on nodeType to figure out if you need to handle key or key2. You don't tell us anything about the types Key and Key2 so I am writing psudo code here (replace ...):

    int searchID(FILE *indexFile, struct bNode *node, int id) {
        if (node->nodeType == LEAF) {
            for (int i = 0; i < node->numKeys; i++) {
                if(nodeType == ... && node->key[i].id == id)
                        return node->key[i].rrn;
                else if(nodeType == ... && node->key2[i] ... )
                        ...
            }
        } else {
            ...
        }
        return -1;
    }```