示例#1
0
文件: ydb_log.c 项目: pombredanne/ydb
struct log *log_new_fast(struct db *db, uint64_t log_number,
			 struct dir *log_dir, struct dir *index_dir,
			 struct bitmap *bitmap)
{
	struct log *log = _log_new(db, log_number, log_dir, index_dir);
	if (log == NULL) {
		return NULL;
	}
	char *idx_file = idx_filename(log_number);
	struct hashdir *hdsets = hashdir_new_load(db, index_dir, idx_file);
	if (hdsets == NULL) {
		log_warn(db, "Can't find index file \"%s\".", idx_file);
		log_free(log);
		return NULL;
		/* log_warn(db, "Can't find index file \"%s\". Trying rebuild.", */
		/* 	 idx_file); */
		/* hdsets = hashdir_new(db); */
		/* struct hashdir *hdall = hashdir_new(db); */
		/* _log_replay(log->reader, hdall, hdsets); */
		/* hashdir_free(hdall); /\* not interested in deletions *\/ */
		/* hashdir_freeze(hdsets); */
		/* int r = hashdir_save(hdsets, index_dir, idx_file); */
		/* if (r == -1) { */
		/* 	log_error(db, "Can't save index file \"%s\".", idx_file); */
		/* } */
	}

	int s = 0;
	int i;
	int hpos_max = hashdir_size(hdsets);
	for (i=1; i < hpos_max; i++) {
		struct hashdir_item hi = hashdir_get(hdsets, i);
		if (bitmap_get(bitmap, hi.bitmap_pos) == 0) { /* add */
			stddev_add(&log->used_size, hi.size);
		} else { /* delete */
			int r = hashdir_del(hdsets, i);
			if (r != -1) {
				s += hashdir_del_last(hdsets);
				/* Visit this element once more. */
				i--;
			}
			hpos_max--;
		}
	}

	log->hashdir = hdsets;
	if (s > 4) {
		int r = hashdir_save(log->hashdir, log->index_dir,
				     idx_filename(log->log_number));
		if (r == -1) {
			log_warn(log->db, "Unable to save index for "
				 "log %llx.",
				 (unsigned long long)log->log_number);
		}
	}

	return log;
}
示例#2
0
文件: ydb_log.c 项目: pombredanne/ydb
int log_add(struct log *log, struct hashdir_item hdi)
{
	stddev_add(&log->used_size, hdi.size);
	return hashdir_add(log->hashdir, hdi);
}
示例#3
0
void thread_loop(void *userdata)
{
	struct state *state = userdata;

	pthread_spin_init(&state->lock, PTHREAD_PROCESS_PRIVATE);

	char send_buf[PKT_SIZE], recv_buf[PKT_SIZE];
	struct msghdr *msg = calloc(2, sizeof(struct msghdr));
	struct iovec *iovec = calloc(2, sizeof(struct iovec));
	int i;
	for (i = 0; i < 2; i++) {
		msg[i].msg_iov = &iovec[i];
		msg[i].msg_iovlen = 1;
		iovec[i].iov_len = sizeof(send_buf);
	}

	iovec[0].iov_base = send_buf;
	iovec[1].iov_base = recv_buf;

	char pktinfo[4096];
	msg[1].msg_control = pktinfo;
	msg[1].msg_controllen = sizeof(pktinfo);

	uint64_t packet_no = 0;
	while (1) {
		int fd = net_connect_udp(state->target_addr, state->src_port,
					 state->busy_poll);

		struct timeval tv = {1, 0}; // 1 second
		int r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv,
				   sizeof(tv));
		if (r < 0) {
			PFATAL("setsockopt(SO_RCVTIMEO)");
		}

		for (;; packet_no++) {
			memset(send_buf, 0, sizeof(send_buf));
			snprintf(send_buf, sizeof(send_buf), "%i-%li-%lu",
				 getpid(), gettid(), packet_no);

			uint64_t t0 = realtime_now(), t1 = 0, tp = 0;
			int r = sendmsg(fd, &msg[0], 0);
			if (r <= 0) {
				if (errno == EAGAIN || errno == EWOULDBLOCK ||
				    errno == ECONNREFUSED) {
					break;
				}
				if (errno == EINTR) {
					continue;
				}
				PFATAL("sendmmsg()");
			}

			msg[1].msg_controllen = sizeof(pktinfo);
			while (1) {
				int flags = state->polling ? MSG_DONTWAIT : 0;
				r = recvmsg(fd, &msg[1], flags);
				t1 = realtime_now();
				if (t1 - t0 >= 1000000000) {
					/* No msg for 1s */
					errno = ECONNREFUSED;
					break;
				}

				if (r <= 0 &&
				    (errno == EINTR || errno == EAGAIN ||
				     errno == EWOULDBLOCK)) {
					continue;
				}

				if (r == 0 && state->polling) {
					continue;
				}
				break;
			}

			if (r <= 0 && errno == ECONNREFUSED) {
				sleep(1);
				break;
			}

			if (r <= 0) {
				PFATAL("recvmmsg()");
			}

			if (memcmp(send_buf, recv_buf, sizeof(recv_buf)) != 0) {
				fprintf(stderr, "[!] bad message\n");
				sleep(1);
				break;
			}

			struct cmsghdr *cmsg;
			for (cmsg = CMSG_FIRSTHDR(&msg[1]); cmsg;
			     cmsg = CMSG_NXTHDR(&msg[1], cmsg)) {
				switch (cmsg->cmsg_level) {
				case SOL_SOCKET:
					switch (cmsg->cmsg_type) {
					case SO_TIMESTAMPNS: {
						struct timespec *ts =
							(struct timespec *)
							CMSG_DATA(cmsg);
						tp = TIMESPEC_NSEC(ts);
						break;
					}
					}
					break;
				}
			}

			pthread_spin_lock(&state->lock);
			stddev_add(&state->stddev, t1 - t0);
			if (tp != 0) {
				stddev_add(&state->stddev_packet, t1 - tp);
			}
			pthread_spin_unlock(&state->lock);
		}
		close(fd);
	}
}