vendredi 7 octobre 2016

Is there a way in C that can replace pointers with pipe in a non linked list way, and also generate the node integer ID?

I'm creating this function right now calls addnode in my C program structure right now; my program will start by calling the routine to add one node. So far I can't seem to figure out how to use pipes replacing the pointers to send messages in a non-linked list way.

The addNode routine will know that no nodes have been created. So, it will fork and the child process will consider itself to be the initial node. Each addNode call will send an addNode message through the initial pipe. addNode includes a node ID to be used. The receiving process will either (a) accept the addNode message and insert a new node with the specified ID after itself or (b) pass the message along until the correct process receives it.

For background of this program, this code is chord simulation of distributed hash table (DHT). The program will read an initial set of key values from a text file of random numbers. There's one process for each node in ring. Each node (process) will communicate with its successor node (process) using a pipe between the two processes. So basically it's using pipe instead of linked list.

The program starts with a single node (with randomly assigned ID). When a new node is created, a new process is forked, pipes created and/or rearranged, and keys properly assigned, by passing data through the network of pipes to get the data items to the correct node.

So here are my two question for my function:

1) What is the right way to create nodeID that pass through my function? Each node is assigned a random number in the range 0-63 when it is created (using the appropriate Linux syscall for random numbers). For my node id part, I just declared my nodeID. That's definitely wrong, how should I generate a random node ID?

2) How do I use pipe replace the linked list, I'm not sure how to make sure a key is stored when the message is accepted. Right I just used the basic pipe concept to use a string to create a message. I'm not sure that's correct way to do it. How do I pass or insert without a linked list in the pipe? I meant using pipes as pointers. Right now my function is expressed in a linked list, how do I use a non-linked list to send the message? SO far my pipe is a written in a poor way, I'm not even sure it's right.

Here is my code:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>



typedef struct
{
    int myNode;
    int pipeFromPrevious;
    int pipeToNext;
    struct chennode_s *next;
} chennode_s;



chennode_s* createNewNode(int iNodeId, int iPrevPipe, int iNextPipe)
{
    // allocate a new empty chennode on the heap
    chennode_s* myNewNode = malloc(sizeof(chennode_s));
    // if that was successful, fill it in
    if (myNewNode != NULL)
    {
        myNewNode->myNode           = iNodeId;
        myNewNode->pipeFromPrevious = iPrevPipe;
        myNewNode->pipeToNext       = iNextPipe;
        myNewNode->next             = NULL;
    }
    else
    {
        // detecting errors is a REALLY IMPORTANT debugging aid! :-)
        fprintf (stderr, "dang, cannot create a new node...");
    }
    // now, return the new node to the caller
    return myNewNode;
}


//Then some functions to insert a new node into the list//
//Searched linked list for this
void addNode(int nodeId, chennode_s  **list) {
    if (pipe (mypipe)) {
        fprintf (stderr, "Pipe failed.\n");
        return EXIT_FAILURE;
    }
    // Create a new node struct,
    //find the correct place in the list for it, splice it in and then set pipeFromPrevious in the new node to mypipe[0] and
    // pipeToNext in the *preceding* node to mypipe[1]
    //(unless this is the first node, in which case the main process should keep track of mypipe[1] directly
    newNode = createNewNode(nodeId, mypipe[0], mypipe[1]);
    // if node created OK, deal with it
    if (newNode != NULL)
    {
        // maybe insert newNode into your list here


        // now do the forking stuff for this node...
        pid = fork();
        if (pid == 0) {
            //display message
            close (mypipe[1]);
            node_mainloop();
        } else {
            close (mypipe[0]);
        }
    }
}

void exitRing() {
    //This routine will send an EXITRING message through the initial pipe.
    //The receiving process will pass the message along, then exit.
}

void listData() {
    //This routine will send a LISTDATA message through the initial pipe.
    //The receiving process will list its node ID and the keys that it stores, then pass the message along.
}


void addKey (int key)
{

        //if (I should store this value)
        //{
            //store it;
        //}
        //else
        //{
            //send ADDKEY message to next node in the ring;
        //}

    // This is incomplete because the nodes may need to be rebalanced as part of this


}


// the main program has to be declared like this, and it is easiest to have it here at the bottom, and call to routines above it, so you don't have to forward-declare the routines.
int main(int argc, const char * argv[])
{


    FILE * pFile;
    pFile=fopen ("key.dat","r");
    if (pFile==NULL)
    { // best to ALWAYS use braces, even for a single line, in case you add a line later
        perror ("Error, no keyfile found");
    }
    else
    {
        do  // loop through each line of file...

        {
            // 1. read a line...
            size_t lineLen;
            char* line = fgetln(pFile, &lineLen);
            // 2. parse line into data you need (use "strtol()" perhaps?)
            // 3. then create a node with the data...
            // 4. and add the node to your list etc...
        } while (!eof of file...)
        fclose (pFile);
    }

    return 0;
}




Aucun commentaire:

Enregistrer un commentaire