<commit_before>/*
   Copyright 2010 <NAME>

   This file is part of Tundra.

   Tundra is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   Tundra 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.

   You should have received a copy of the GNU General Public License
   along with Tundra.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "files.h"
#include "engine.h"

#include <assert.h>
#include <string.h>

static pthread_mutex_t *
get_object_lock(td_engine *engine, uint32_t hash)
{
	return &engine->object_locks[hash % TD_OBJECT_LOCK_COUNT];
}

const td_stat *
td_stat_file(td_engine *engine, td_file *f)
{
	double t1 = 0.0;
	int did_stat = 0;
	int collect_stats = 0;
	int result;
	pthread_mutex_t *objlock;

	collect_stats = td_debug_check(engine, TD_DEBUG_STATS);

	if (collect_stats)
		t1 = td_timestamp();

	objlock = get_object_lock(engine, f->hash);
	td_mutex_lock_or_die(objlock);

	if (f->stat_dirty)
	{
		if (0 != fs_stat_file(f->path, &f->stat))
		{
			f->stat.flags = 0;
			f->stat.size = 0;
			f->stat.timestamp = 0;
		}
		f->stat_dirty = 0;
		result = 1;
	}
	else
		result = 0;

	td_mutex_unlock_or_die(objlock);

	if (collect_stats)
	{
		double t2 = td_timestamp();
		td_mutex_lock_or_die(engine->lock);
		++engine->stats.stat_calls;
		engine->stats.stat_time += t2 - t1;
		engine->stats.stat_checks += did_stat;
		td_mutex_unlock_or_die(engine->lock);
	}

	return &f->stat;
}

void
td_touch_file(td_engine *engine, td_file *f)
{
	pthread_mutex_t *obj_lock;
	obj_lock = get_object_lock(engine, f->hash);

	td_mutex_lock_or_die(obj_lock);
	f->stat_dirty = 1;
	f->signature_dirty = 1;
	td_mutex_unlock_or_die(obj_lock);
}

td_digest *
td_get_signature(td_engine *engine, td_file *f)
{
	int count_bump = 0;
	const int dry_run = engine->settings.dry_run;
	double t1, t2;
	pthread_mutex_t *object_lock;

	t1 = td_timestamp();

	object_lock = get_object_lock(engine, f->hash);
	td_mutex_lock_or_die(object_lock);

	if (f->signature_dirty)
	{
		if (!dry_run)
		{
			assert(f->signer);

			if (f->signer->is_lua)
				td_croak("lua signers not implemented yet");
			else
				(*f->signer->function.function)(engine, f, &f->signature);

			count_bump = 1;
		}
		else
		{
			memset(&f->signature, 0, sizeof(f->signature));
		}

		f->signature_dirty = 0;
	}

	td_mutex_unlock_or_die(object_lock);

	/* modify stats once we're back in the engine lock */
	td_mutex_lock_or_die(engine->lock);
	if (count_bump && !f->signer->is_lua)
	{
		td_sign_fn function = f->signer->function.function;
		if (td_sign_digest == function)
			++engine->stats.timestamp_sign_count;
		else if (td_sign_digest == function)
			++engine->stats.md5_sign_count;
	}

	t2 = td_timestamp();
	engine->stats.file_signing_time += t2 - t1;
	td_mutex_unlock_or_die(engine->lock);

	return &f->signature;
}

td_file *td_parent_dir(td_engine *engine, td_file *f)
{
	int i;
	char path_buf[512];

	if (f->path_len >= sizeof(path_buf) - 1)
		td_croak("path too long: %s", f->path);

	strncpy(path_buf, f->path, sizeof(path_buf));

	for (i = f->path_len - 1; i >= 0; --i)
	{
		char ch = path_buf[i];<commit_msg>Removed unused var. Fixed stats bug.<commit_after>/*
   Copyright 2010 <NAME>

   This file is part of Tundra.

   Tundra is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   Tundra 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.

   You should have received a copy of the GNU General Public License
   along with Tundra.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "files.h"
#include "engine.h"

#include <assert.h>
#include <string.h>

static pthread_mutex_t *
get_object_lock(td_engine *engine, uint32_t hash)
{
	return &engine->object_locks[hash % TD_OBJECT_LOCK_COUNT];
}

const td_stat *
td_stat_file(td_engine *engine, td_file *f)
{
	double t1 = 0.0;
	int did_stat = 0;
	int collect_stats = 0;
	pthread_mutex_t *objlock;

	collect_stats = td_debug_check(engine, TD_DEBUG_STATS);

	if (collect_stats)
		t1 = td_timestamp();

	objlock = get_object_lock(engine, f->hash);
	td_mutex_lock_or_die(objlock);

	if (f->stat_dirty)
	{
		if (0 != fs_stat_file(f->path, &f->stat))
		{
			f->stat.flags = 0;
			f->stat.size = 0;
			f->stat.timestamp = 0;
		}
		f->stat_dirty = 0;
	}

	td_mutex_unlock_or_die(objlock);

	if (collect_stats)
	{
		double t2 = td_timestamp();
		td_mutex_lock_or_die(engine->lock);
		++engine->stats.stat_calls;
		engine->stats.stat_time += t2 - t1;
		engine->stats.stat_checks += did_stat;
		td_mutex_unlock_or_die(engine->lock);
	}

	return &f->stat;
}

void
td_touch_file(td_engine *engine, td_file *f)
{
	pthread_mutex_t *obj_lock;
	obj_lock = get_object_lock(engine, f->hash);

	td_mutex_lock_or_die(obj_lock);
	f->stat_dirty = 1;
	f->signature_dirty = 1;
	td_mutex_unlock_or_die(obj_lock);
}

td_digest *
td_get_signature(td_engine *engine, td_file *f)
{
	int count_bump = 0;
	const int dry_run = engine->settings.dry_run;
	double t1, t2;
	pthread_mutex_t *object_lock;

	t1 = td_timestamp();

	object_lock = get_object_lock(engine, f->hash);
	td_mutex_lock_or_die(object_lock);

	if (f->signature_dirty)
	{
		if (!dry_run)
		{
			assert(f->signer);

			if (f->signer->is_lua)
				td_croak("lua signers not implemented yet");
			else
				(*f->signer->function.function)(engine, f, &f->signature);

			count_bump = 1;
		}
		else
		{
			memset(&f->signature, 0, sizeof(f->signature));
		}

		f->signature_dirty = 0;
	}

	td_mutex_unlock_or_die(object_lock);

	/* modify stats once we're back in the engine lock */
	td_mutex_lock_or_die(engine->lock);
	if (count_bump && !f->signer->is_lua)
	{
		td_sign_fn function = f->signer->function.function;
		if (td_sign_timestamp == function)
			++engine->stats.timestamp_sign_count;
		else if (td_sign_digest == function)
			++engine->stats.md5_sign_count;
	}

	t2 = td_timestamp();
	engine->stats.file_signing_time += t2 - t1;
	td_mutex_unlock_or_die(engine->lock);

	return &f->signature;
}

td_file *td_parent_dir(td_engine *engine, td_file *f)
{
	int i;
	char path_buf[512];

	if (f->path_len >= sizeof(path_buf) - 1)
		td_croak("path too long: %s", f->path);

	strncpy(path_buf, f->path, sizeof(path_buf));

	for (i = f->path_len - 1; i >= 0; --i)
	{
		char ch = path_buf[i];
{'fraction_non_alphanumeric': 0.1279965131483365, 'fraction_numerical': 0.011913409850355949, 'mean_word_length': 4.1030392883617495, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '559167', 'n_tokens_mistral': 2836, 'n_tokens_neox': 2623, 'n_words': 629}