コード例 #1
0
ファイル: genders.c プロジェクト: BenCasses/genders
/* 
 * _genders_copy_attrvalslist
 *
 * Copy contents of the attrvalslist list into the handlecopy.
 *
 */
static int
_genders_copy_attrvalslist(genders_t handle, genders_t handlecopy)
{
  ListIterator attrvalslistitr = NULL;
  ListIterator attrvalsitr = NULL;
  genders_attrvals_container_t avc;
  genders_attrvals_container_t newavc = NULL;
  genders_attrval_t newav = NULL;
  int rv = -1;

  __list_iterator_create(attrvalslistitr, handle->attrvalslist);
  while ((avc = list_next(attrvalslistitr)))
    {
      genders_attrval_t av = NULL;

      __list_iterator_create(attrvalsitr, avc->attrvals);

      __xmalloc(newavc,
		genders_attrvals_container_t,
		sizeof(struct genders_attrvals_container));
      __list_create(newavc->attrvals, _genders_list_free_genders_attrval);
      newavc->index = avc->index;

      while ((av = list_next(attrvalsitr)))
	{
	  __xmalloc(newav, genders_attrval_t, sizeof(struct genders_attrval));
	  __xstrdup(newav->attr, av->attr);
	  if (av->val)
	    __xstrdup(newav->val, av->val);
	  else
	    newav->val = NULL;
	  newav->val_contains_subst = av->val_contains_subst;
	  __list_append(newavc->attrvals, newav);
	  newav = NULL;
	}
      
      __list_append(handlecopy->attrvalslist, newavc);
      newavc = NULL;
  }
  
  rv = 0;
 cleanup:
  if (rv < 0)
    {
      if (newav)
	{
	  free(newav->attr);
	  free(newav->val);
	  free(newav);
	}
      if (newavc)
	{
	  __list_destroy(newavc->attrvals);
	  free(newavc);
	}
    }
  __list_iterator_destroy(attrvalslistitr);
  __list_iterator_destroy(attrvalsitr);
  return rv;
}
コード例 #2
0
ファイル: genders.c プロジェクト: BenCasses/genders
/* 
 * _genders_copy_nodeslist
 *
 * Copy contents of the nodeslist list into the handlecopy.
 *
 */
static int
_genders_copy_nodeslist(genders_t handle, genders_t handlecopy)
{
  ListIterator itr = NULL;
  genders_node_t n = NULL;
  genders_node_t newn = NULL;
  int rv = -1;

  __list_iterator_create(itr, handle->nodeslist);
  while ((n = list_next(itr)))
    {
      __xmalloc(newn, genders_node_t, sizeof(struct genders_node));
      __xstrdup(newn->name, n->name);
      __list_create(newn->attrlist, NULL);
      newn->attrcount = n->attrcount;
      newn->attrlist_index_size = n->attrlist_index_size;
      __hash_create(newn->attrlist_index,
                    newn->attrlist_index_size,
                    (hash_key_f)hash_key_string,
                    (hash_cmp_f)strcmp,
                    NULL);

      __list_append(handlecopy->nodeslist, newn);
      newn = NULL;
    }
  
  rv = 0;
 cleanup:
  if (rv < 0)
    {
      if (newn)
	{
	  free(newn->name);
	  __list_destroy(newn->attrlist);
	  __hash_destroy(newn->attrlist_index);
	  free(newn);
	}
    }
  __list_iterator_destroy(itr);
  return rv;
}
コード例 #3
0
ファイル: slave.c プロジェクト: rv1/esb
int beginSlavery(int fd)
{
    uint16_t randContext[3];
    for(int i = 0; i < 3; i++)
    {
        randContext[i] = time(NULL) ^ getpid();
    }
    
    int returnCode = -1;
    
    json_t* params = NULL;
    json_t* nextCommand = NULL;
    
    char** values = NULL;
    
    struct workerTask* tasks = NULL;
    
    uint32_t connPoolSize = 128;
    uint32_t connPoolCount = 0;
    void** connPool = __xmalloc(sizeof(void*) * connPoolSize);
    memset(connPool, 0, sizeof(void*) * connPoolSize);
    
    //recieve initial parameters
    params = readCommand(fd, 5000);
    if(!params)
    {
        fprintf(stderr, "No initialization packet\n");
        goto exit;
    }
    
    //make sure the initial packet has all of the required info
    uint64_t slaveID;
    const char* command;
    const char* address;
    const char* username;
    const char* password;
    const char* tableName;
    int port;
    int errorChecking;
    int valueLength;
    int result = json_unpack(params, "{s:s, s:s, s:i, s:I, s:s, s:s, s:s, s:b, s:i}",
                             "command",         &command,
                             "address",         &address,
                             "port",            &port,
                             "slave-id",        &slaveID,
                             "username",        &username,
                             "password",        &password,
                             "table",           &tableName,
                             "error-checking",  &errorChecking,
                             "value-length",    &valueLength);
    if(result != 0 || strcmp(command, "init") || port <= 0 || port > 65535)
    {
        fprintf(stderr, "Invalid initialization packet recieved\n");
        goto exit;
    }

    uint64_t numKeys = 0;
    
    //loop and execute commands from the master
    while(1)
    {
        nextCommand = readCommand(fd, 15000);
        if(!nextCommand)
        {
            fprintf(stderr, "Invalid next command\n");
            goto exit;
        }
                        
        const char* command;
        int result = json_unpack(nextCommand, "{s:s}", "command", &command);
        if(result == -1)
        {
            fprintf(stderr, "Packet missing command field\n");
            goto exit;
        }
        
        //parse commands and modify keyRange array if needed
        struct workerTask task;
        
        if(!strcmp(command, "add"))
        {
            uint64_t numKeysToAdd;
            int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToAdd);
            if(result == -1)
            {
                goto exit;
            }

            if(errorChecking)
            {
                values = __xrealloc(values, sizeof(char*) * (numKeys + numKeysToAdd));
                for(uint64_t i = 0; i < numKeysToAdd; i++)
                {
                    values[numKeys + i] = __xmalloc(valueLength + 1);
                    for(int j = 0; j < valueLength; j++)
                    {
                        values[numKeys + i][j] = (erand48(randContext) * 26) + 'A';
                    }
                    values[numKeys + i][valueLength] = '\0';
                }
            }
            task.startingKey = slaveID + numKeys;
            task.numKeys = numKeysToAdd;
            task.type = kClientAddKeys;
            task.values = values;
            numKeys += task.numKeys;
        }
        else if(!strcmp(command, "remove"))
        {
            uint64_t numKeysToRemove;
            
            int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToRemove);
            if(result == -1)
            {
                goto exit;
            }
            
            if(errorChecking)
            {
                uint64_t position = numKeys - numKeysToRemove;
                for(uint64_t i = 0; i < numKeysToRemove; i++)
                {
                    free(values[position + i]);
                }
                values = __xrealloc(&values, sizeof(char*) * (numKeys - numKeysToRemove));
            }
            if(numKeysToRemove > numKeys)
            {
                goto exit;
            }
            task.startingKey = slaveID + numKeys - numKeysToRemove;
            task.numKeys = numKeysToRemove;
            task.type = kClientRemoveKeys;
            task.values = NULL;
            numKeys -= numKeysToRemove;
        }
        else if(!strcmp(command, "test"))
        {
            json_t* array = json_object_get(nextCommand, "workload");

            //right now we only need 1 workload type
            if(!(json_is_array(array) && json_array_size(array) == kWorkloadTypes))
            {
                goto exit;
            }
            for(int i = 0; i < kWorkloadTypes; i++)
            {
                task.workloadComposition[i] = json_number_value(json_array_get(array, i));
            }
            int result = json_unpack(nextCommand, "{s:I}", "amount", &task.count);
            if(result == -1)
            {
                goto exit;
            }
            task.startingKey = slaveID;
            task.numKeys = numKeys;
            task.values = values;
            task.type = kClientRunWorkload;
        }
        else if(!strcmp(command, "quit"))
        {
            returnCode = 0;
            goto exit;
        }
        else
        {
            fprintf(stderr, "unknown command from client: %s\n", command);
            goto exit;
        }
        
        int numClients;
        result = json_unpack(nextCommand, "{s:i, s:F}", "num-clients", &numClients, "throughput", &task.throughput);
        if(result == -1)
        {
            fprintf(stderr, "Packet missing number of clients or throughput value\n");
            goto exit;
        }
                
        task.connOpenDelay = 0;
        
        //fill out the generic task information
        task.table = tableName;
        task.valueSize = valueLength;
        task.workerID = slaveID;
        task.hostname = address;
        task.username = username;
        task.password = password;
        task.port = port;
        
        //split the request between the clients
        while(numClients >= connPoolSize)
        {
            size_t oldSize = connPoolSize;
            connPoolSize *= 8;
            connPool = __xrealloc(connPool, connPoolSize * sizeof(void*));
            memset(&connPool[oldSize], 0, sizeof(void*) * oldSize * 7);
        }
        
        if(numClients < connPoolCount)
        {
            for(int i = connPoolCount - 1; i >= numClients; i--)
            {
                storage_disconnect(connPool[i]);
                connPool[i] = NULL;
            }
        }
        
        tasks = __xmalloc(sizeof(struct workerTask) * numClients);
        splitTasks(&task, tasks, numClients, connPool);
                
        //perform the request
        json_t* requestResponse;
        performRequest(tasks, numClients, &requestResponse);
        
        //save the connections for next time
        for(int i = 0; i < numClients; i++)
        {
            connPool[i] = tasks[i].conn;
        }
        connPoolCount = numClients;
        
        //send the result back to the master
        char* serialResponse = json_dumps(requestResponse, JSON_COMPACT);
        json_decref(requestResponse);
        size_t len = strlen(serialResponse);
        if(len > 1048576)
        {
            fprintf(stderr, "Response too large (%zd)\n", len);
            free(serialResponse);
            goto exit;
        }
        char sizeBuf[9];
        sprintf(sizeBuf, "%08d", (int)len);
        sendAll(fd, sizeBuf, 8);
        
        if(sendAll(fd, serialResponse, strlen(serialResponse)) == -1)
        {
            free(serialResponse);
            goto exit;
        }
        free(serialResponse);

        free(tasks);
        tasks = NULL;        
        
        //free the parsed command
        json_decref(nextCommand);
        nextCommand = NULL;
    }
    
exit:
    for(uint32_t i = 0; i < connPoolCount; i++)
    {
        storage_disconnect(connPool[i]);
    }
    free(connPool);
    free(tasks);
    json_decref(nextCommand);
    json_decref(params);
    if(values)
    {
        for(uint64_t i = 0; i < numKeys; i++)
        {
            free(values[i]);
        }
        free(values);
    }
    return returnCode;
}
コード例 #4
0
ファイル: slave.c プロジェクト: rv1/esb
void performRequest(struct workerTask* tasks, int taskCount, json_t** result)
{
    uint64_t* latencyResults = __xmalloc(sizeof(uint64_t) * kNumLatencyBuckets);
    memset(latencyResults, 0, sizeof(uint64_t) * kNumLatencyBuckets);
    
    //create a thread for each client
    pthread_t* threads = __xmalloc(sizeof(pthread_t) * taskCount);
    for(int i = 0; i < taskCount; i++)
    {
        //don't start a worker if it does'nt have any keys
        if(tasks[i].numKeys == 0)
        {
            taskCount = i;
            break;
        }
        
        tasks[i].latencyResults = latencyResults;
        
        //TODO - possibly reduce stack size for clients
        pthread_attr_t attributes;
        pthread_attr_init(&attributes);
        int result = pthread_attr_setstacksize(&attributes, 512*1024);
        if(result)
        {
            char buf[256];
            strerror_r(result, buf, sizeof(buf));
            fprintf(stderr, "Error setting stack size of thread: %s\n", buf);
            taskCount = i;
            break;
        }
        
        result = pthread_create(&threads[i], &attributes, testClient, &tasks[i]);
        if(result)
        {
            char buf[256];
            strerror_r(result, buf, sizeof(buf));
            fprintf(stderr, "Error creating thread %d: %s\n", i, buf);
            taskCount = i;
            break;
        }
    }
    
    //get the results
    
    //TODO add a timeout to allow the forceful killing of threads
    
    
    //create a json object to store the results
    *result = json_object();
    json_t* errorArray = json_array();
    json_t* resultArray = json_array();
    json_object_set_new(*result, "errors", errorArray);
    json_object_set_new(*result, "latency", resultArray);
    
    for(int i = 0; i < taskCount; i++)
    {
        void* threadResult;
        pthread_join(threads[i], &threadResult);
        
        //returns a pointer to an error message - NULL means no error
        if(threadResult)
        {
            json_t* newError = json_object();
            json_object_set_new(newError, "cause", json_string(threadResult));
            json_object_set_new(newError, "client-id", json_integer(tasks[i].workerID));
            json_array_append_new(errorArray, newError);
        }
    }
    
    //add the latency stats to the json object
    for(int i = 0; i < kNumLatencyBuckets; i++)
    {
        if(latencyResults[i])
        {
            json_array_append_new(resultArray, json_integer(i));
            json_array_append_new(resultArray, json_integer(latencyResults[i]));
        }
    }
    free(threads);
    free(latencyResults);
}