<commit_before>/*
 * Parcelkeeper - support daemon for the OpenISR (R) system virtual disk
 *
 * Copyright (C) 2006-2010 Carnegie Mellon University
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.  A copy of the GNU General Public License
 * should have been distributed along with this program in the file
 * LICENSE.GPL.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include "defs.h"
#include "fuse_defs.h"

typedef gboolean (stat_handler)(void *data, const char *name);

/* state->stats_lock must be held if stat_handler ever returns TRUE */
static gchar *_statistic(struct pk_state *state, stat_handler *handle,
			void *data)
{
	if (handle(data, "bytes_read"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.bytes_read);
	if (handle(data, "bytes_written"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.bytes_written);
	if (handle(data, "chunk_reads"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.chunk_reads);
	if (handle(data, "chunk_writes"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.chunk_writes);
	if (handle(data, "chunk_errors"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.chunk_errors);
	if (handle(data, "cache_hits"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.cache_hits);
	if (handle(data, "cache_misses"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.cache_misses);
	if (handle(data, "compression_ratio_pct")) {
		if (state->stats.chunk_writes == 0)
			return g_strdup("n/a\n");
		return g_strdup_printf("%.1f\n", 100.0 *
					state->stats.data_bytes_written /
					(state->stats.chunk_writes *
					state->parcel->chunksize));
	}
	if (handle(data, "whole_chunk_updates"))
		return g_strdup_printf("%"PRIu64"\n",
					state->stats.whole_chunk_updates);
	return NULL;
}

static gboolean _stat_enumerate(void *data, const char *name)
{
	g_ptr_array_add(data, g_strdup(name));
	return FALSE;
}

gchar **stat_list(struct pk_state *state)
{
	GPtrArray *arr;

	arr = g_ptr_array_new();
	_statistic(state, _stat_enumerate, arr);
	g_ptr_array_add(arr, NULL);
	return (gchar **) g_ptr_array_free(arr, FALSE);
}

static gboolean _stat_compare(void *data, const char *name)
{
	return g_str_equal(data, name);
}

gchar *stat_get(struct pk_state *state, const char *name)
{
	gchar *ret;

	g_mutex_lock(state->stats_lock);
	ret = _statistic(state, _stat_compare, (char *) name);
	g_mutex_unlock(state->stats_lock);
	return ret;
}

int stat_open(struct pk_state *state, const char *name)
{
	gchar *buf;
	int fh;

	buf = stat_get(state, name);
	if (buf == NULL)<commit_msg>pk: Improve locking rules for _statistic()<commit_after>/*
 * Parcelkeeper - support daemon for the OpenISR (R) system virtual disk
 *
 * Copyright (C) 2006-2010 Carnegie Mellon University
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.  A copy of the GNU General Public License
 * should have been distributed along with this program in the file
 * LICENSE.GPL.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include "defs.h"
#include "fuse_defs.h"

typedef gboolean (stat_handler)(void *data, const char *name);

#define RETURN_FORMAT(lock, str, args...) do {	\
	g_mutex_lock(lock);			\
	ret = g_strdup_printf(str, ## args);	\
	g_mutex_unlock(lock);			\
	return ret;				\
} while (0)

static gchar *_statistic(struct pk_state *state, stat_handler *handle,
			void *data)
{
	gchar *ret;

	if (handle(data, "bytes_read"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.bytes_read);
	if (handle(data, "bytes_written"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.bytes_written);
	if (handle(data, "chunk_reads"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.chunk_reads);
	if (handle(data, "chunk_writes"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.chunk_writes);
	if (handle(data, "chunk_errors"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.chunk_errors);
	if (handle(data, "cache_hits"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.cache_hits);
	if (handle(data, "cache_misses"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.cache_misses);
	if (handle(data, "compression_ratio_pct")) {
		g_mutex_lock(state->stats_lock);
		if (state->stats.chunk_writes)
			ret = g_strdup_printf("%.1f\n", 100.0 *
					state->stats.data_bytes_written /
					(state->stats.chunk_writes *
					state->parcel->chunksize));
		else
			ret = g_strdup("n/a\n");
		g_mutex_unlock(state->stats_lock);
		return ret;
	}
	if (handle(data, "whole_chunk_updates"))
		RETURN_FORMAT(state->stats_lock, "%"PRIu64"\n",
					state->stats.whole_chunk_updates);
	return NULL;
}

#undef RETURN_FORMAT

static gboolean _stat_enumerate(void *data, const char *name)
{
	g_ptr_array_add(data, g_strdup(name));
	return FALSE;
}

gchar **stat_list(struct pk_state *state)
{
	GPtrArray *arr;

	arr = g_ptr_array_new();
	_statistic(state, _stat_enumerate, arr);
	g_ptr_array_add(arr, NULL);
	return (gchar **) g_ptr_array_free(arr, FALSE);
}

static gboolean _stat_compare(void *data, const char *name)
{
	return g_str_equal(data, name);
}

gchar *stat_get(struct pk_state *state, const char *name)
{
	return _statistic(state, _stat_compare, (char *) name);
}

int stat_open(struct pk_state *state, const char *name)
{
	gchar *buf;
	int fh;

	buf = stat_get(state, name);
	if (buf == NULL)
{'fraction_non_alphanumeric': 0.13464325978418426, 'fraction_numerical': 0.009985504912224191, 'mean_word_length': 4.7606679035250465, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3483532', 'n_tokens_mistral': 2379, 'n_tokens_neox': 2207, 'n_words': 567}