Exemple #1
0
/**
 * Opens a directory in cache fs form (ie. client cached index + data files)
 */
int cache_open_fs_dir(cache_t* cache, const char* directory)
{
	DIR *dir = opendir(directory);
	struct dirent *entry;
	int num_indices = 0;

	sorted_list_t* index_list = object_new(sorted_list);
	index_list->compare_func = strcmp_wrap;
	if (dir == NULL) {
		return 1;
	}

	char data_file[256];
	while ((entry = readdir(dir)) != NULL) {
		if (strstr(entry->d_name, "idx")) {
			index_list_node_t* node = (index_list_node_t*)malloc(sizeof(index_list_node_t));
			strcpy(node->index, entry->d_name);
			sorted_list_insert(index_list, &node->node);
			num_indices++;
		} else if (strstr(entry->d_name, "dat")) {
			sprintf(data_file, "%s/%s", directory, entry->d_name);
		}
	}

	if (data_file == NULL || num_indices == 0) {
		return 1;
	}

	char** index_files = (char**)malloc(sizeof(char*)*num_indices);
	int i = 0;
	while (!list_empty(&index_list->list)) {
		list_node_t* node = list_front(&index_list->list);
		index_list_node_t* index_node = container_of(node, index_list_node_t, node);
		index_files[i] = (char*)malloc(sizeof(char)*256);
		sprintf(index_files[i++], "%s/%s", directory, (char*)index_node->index);
		list_erase(&index_list->list, node);
		free(index_node);
	}
	object_free(index_list);
	closedir(dir);

	cache_open_fs(cache, num_indices, (const char**)index_files, data_file);

	for (int i = 0; i < num_indices; i++) {
		free(index_files[i]);
	}
	free(index_files);

	return 0;
}
Exemple #2
0
void make_screen_list() {
    hash_node_type* n = NULL;
    while(hash_next_item(screen_hash, &n) == HASH_STATUS_OK) {
        host_pair_line* line = (host_pair_line*)n->rec;
        int i;
        for(i = 0; i < HISTORY_DIVISIONS; i++) {
          line->recv[i] /= history_length(i);
          line->sent[i] /= history_length(i);
        }

        /* Don't make a new, sorted screen list if order is frozen
         */
        if(!options.freezeorder) {
            sorted_list_insert(&screen_list, line);
        } 
	 
    }
}
Exemple #3
0
/* 
recv_window_receive
	takes in a window, a pointer, the length associated with the memory pointed to by
	that pointer, and also the sequence number of the given data (the first octet of that
	data). This function performs all the necessary sliding window functions, and then returns
	the ACK number to send back. If there is no such number (ie the window didn't slide at all, 
	it will return -1.

	stores the data directly, so give it something that it can free!
*/
void recv_window_receive_synchronized(recv_window_t recv_window, void* data, uint32_t length, uint32_t seqnum){
	int offset = recv_window_validate_seqnum(recv_window, seqnum, length);
	if(offset<0){
		LOG(("seqnum %d not accepted. left: %d\n", seqnum, recv_window->left)); 
		return;
	}

	if(length==0){
		// then theres nothing to do
		return;
	}	
	
	uint32_t to_write = MIN(length-offset, WRAP_DIFF(seqnum, (recv_window->left+recv_window->size)%MAX_SEQNUM, MAX_SEQNUM));
	if(!to_write){
		// then there's also nothing to do
		return;
	}

	/* if the data has a non-zero offset, then we will need to make a new chunk
		   of data that the recv_chunk can point to so that when it frees that void* 
		   pointer it actually does something. Let me illustrate:

		   void* chunk = malloc(100);
		   free(chunk+1); // LEAK!
		   free(chunk);   // good
	*/
 	if(offset > 0){
 		void* new_data = malloc(to_write);
 		memcpy(new_data, data+offset, to_write);
 		free(data);
 		data = new_data;
 	}


	int already_read_overlap = WRAP_DIFF((seqnum+offset)%MAX_SEQNUM, recv_window->read_left, MAX_SEQNUM);
	if(already_read_overlap >= 0)
	{
		to_write -= already_read_overlap;

		ext_array_push(recv_window->data_queue, data+already_read_overlap, to_write);
		free(data);

		recv_window->read_left      += to_write;
		recv_window->available_size -= to_write;

		/* then go through and see if this connects to the next received_chunk */
		recv_chunk_t next_chunk;
		
		int overlap;
		while((next_chunk = sorted_list_peek(recv_window->chunks_received))){		

			/* if the next chunk is farther along then the last byte that's been read, 
			   then just continue */
			if(WRAP_DIFF(next_chunk->seqnum, recv_window->read_left, MAX_SEQNUM) < 0) 
				break;
			
			// better be the same!
			next_chunk = sorted_list_pop(recv_window->chunks_received);

			/* check the overlap between the chunk that you've previously
			   received and the chunk that was just read */
			overlap = WRAP_DIFF(next_chunk->seqnum, recv_window->read_left, MAX_SEQNUM);

			/* if the overlap is less than the length of the chunk (ie the 
			   chunk that was in the received list isn't completely covered
			   by the chunk taht was just pushed) then push its data */
			if(overlap < next_chunk->length){
				ext_array_push(recv_window->data_queue, next_chunk->data+overlap, next_chunk->length-overlap);
	
				/* only incremente the read_left/decrement the available size by 
				   the amount that you actually used from the most recent chunk */
				recv_window->read_left 		+= next_chunk->length-overlap;
				recv_window->available_size -= next_chunk->length-overlap;
			}
			
			/* destroy that chunk */
			recv_chunk_destroy(&next_chunk);
		}
	}
	else
	{
 		sorted_list_insert(recv_window->chunks_received, recv_chunk_init(seqnum, data, to_write)); 
	}	
	
	// inform any interested parties that you just got some new stuff
	pthread_cond_signal(&(recv_window->read_cond));
}