<commit_before>/* SPDX-License-Identifier: LGPL-2.1 */

/*
 * ac_circ_buf.c - A circular buffer of fixed size (power of 2)
 *
 * Based on include/linux/circ_buf.h from
 * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree
 *
 * Copyright (c) 2019		<NAME> <<EMAIL>>
 */

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#include "include/libac.h"

/*
 * How many items are in the buffer
 */
static inline u32 circ_count(const ac_circ_buf_t *cbuf)
{
	return (cbuf->head - cbuf->tail) & (cbuf->size - 1);
}

/*
 * How much free space is in the buffer, 0..size-1
 */
static inline u32 circ_space(const ac_circ_buf_t *cbuf)
{
	return (cbuf->tail - (cbuf->head + 1)) & (cbuf->size - 1);
}

/*
 * How many contiguous items are in the buffer without wrapping
 * around
 */
static inline u32 circ_count_to_end(const ac_circ_buf_t *cbuf)
{
	int end = cbuf->size - cbuf->tail;
	int n = (cbuf->head + end) & (cbuf->size - 1);

	return n < end ? n : end;
}

/*
 * How much contiguous free space is in the buffer without
 * wrapping around
 */
static inline u32 circ_space_to_end(const ac_circ_buf_t *cbuf)
{
	int end = cbuf->size - 1 - cbuf->head;
	int n = (end + cbuf->tail) & (cbuf->size - 1);

	return n <= end ? n : end + 1;
}

static bool is_pow2(u32 val)
{
	return !(val & (val - 1));
}

/**
 * ac_circ_buf_new - create a new circular buffer
 *
 * @size: The required size of the buffer, must be a power of two
 *
 * Returns:
 *
 * A pointer to a newly allocated buffer or NULL on failure
 */
ac_circ_buf_t *ac_circ_buf_new(u32 size)
{
	ac_circ_buf_t *cbuf;

	if (!is_pow2(size))
		return NULL;

	cbuf = malloc(sizeof(ac_circ_buf_t));
	cbuf->head = cbuf->tail = 0;
	cbuf->size = size;
	cbuf->buf = malloc(size * sizeof(void *));

	return cbuf;
}

/**
 * ac_circ_buf_count - how many items are in the buffer
 *
 * @cbuf: The circular buffer to work on
 *
 * Returns:
 *
 * The number of items in the buffer
 */
u32 ac_circ_buf_count(const ac_circ_buf_t *cbuf)
{
	return circ_count(cbuf);
}

/**
 * ac_circ_buf_pushm - push multiple items into the buffer
 *
 * @cbuf: The circular buffer to work on
 * @buf: The item(s) to push into the buffer
 * @count: The number of items contained in @data
 *
 * Returns:
 *
 * 0 on success or -1 if there was no room (contiguous space)
 */
int ac_circ_buf_pushm(ac_circ_buf_t *cbuf, void *buf, size_t count)
{
	if (circ_space_to_end(cbuf) < count)
		return -1;

	memcpy(cbuf->buf + cbuf->head, buf, count * sizeof(void *));
	cbuf->head = (cbuf->head + count) & (cbuf->size - 1);

	return 0;
}

/**
 * ac_circ_buf_push - push an item into the buffer
 *
 * @cbuf: The circular buffer to work on
 * @buf: The item to add
 *
 * Returns:
 *
 * 0 on success or -1 if the buffer is full
 */
int ac_circ_buf_push(ac_circ_buf_t *cbuf, void *buf)
{
	if (circ_space(cbuf) == 0)
		return -1;

	cbuf->buf[cbuf->head] = buf;
	cbuf->head = (cbuf->head + 1) & (cbuf->size - 1);

	return 0;
}

/**
 * ac_circ_buf_popm - pop multiple items from buffer
 *
 * @cbuf: The circular buffer to work on
 * @count: The numbr of items to pop from the buffer
 *
 * Returns:
 *<commit_msg>ac_circ_buf: Fix a comment typo<commit_after>/* SPDX-License-Identifier: LGPL-2.1 */

/*
 * ac_circ_buf.c - A circular buffer of fixed size (power of 2)
 *
 * Based on include/linux/circ_buf.h from
 * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree
 *
 * Copyright (c) 2019		<NAME> <<EMAIL>>
 */

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#include "include/libac.h"

/*
 * How many items are in the buffer
 */
static inline u32 circ_count(const ac_circ_buf_t *cbuf)
{
	return (cbuf->head - cbuf->tail) & (cbuf->size - 1);
}

/*
 * How much free space is in the buffer, 0..size-1
 */
static inline u32 circ_space(const ac_circ_buf_t *cbuf)
{
	return (cbuf->tail - (cbuf->head + 1)) & (cbuf->size - 1);
}

/*
 * How many contiguous items are in the buffer without wrapping
 * around
 */
static inline u32 circ_count_to_end(const ac_circ_buf_t *cbuf)
{
	int end = cbuf->size - cbuf->tail;
	int n = (cbuf->head + end) & (cbuf->size - 1);

	return n < end ? n : end;
}

/*
 * How much contiguous free space is in the buffer without
 * wrapping around
 */
static inline u32 circ_space_to_end(const ac_circ_buf_t *cbuf)
{
	int end = cbuf->size - 1 - cbuf->head;
	int n = (end + cbuf->tail) & (cbuf->size - 1);

	return n <= end ? n : end + 1;
}

static bool is_pow2(u32 val)
{
	return !(val & (val - 1));
}

/**
 * ac_circ_buf_new - create a new circular buffer
 *
 * @size: The required size of the buffer, must be a power of two
 *
 * Returns:
 *
 * A pointer to a newly allocated buffer or NULL on failure
 */
ac_circ_buf_t *ac_circ_buf_new(u32 size)
{
	ac_circ_buf_t *cbuf;

	if (!is_pow2(size))
		return NULL;

	cbuf = malloc(sizeof(ac_circ_buf_t));
	cbuf->head = cbuf->tail = 0;
	cbuf->size = size;
	cbuf->buf = malloc(size * sizeof(void *));

	return cbuf;
}

/**
 * ac_circ_buf_count - how many items are in the buffer
 *
 * @cbuf: The circular buffer to work on
 *
 * Returns:
 *
 * The number of items in the buffer
 */
u32 ac_circ_buf_count(const ac_circ_buf_t *cbuf)
{
	return circ_count(cbuf);
}

/**
 * ac_circ_buf_pushm - push multiple items into the buffer
 *
 * @cbuf: The circular buffer to work on
 * @buf: The item(s) to push into the buffer
 * @count: The number of items contained in @data
 *
 * Returns:
 *
 * 0 on success or -1 if there was no room (contiguous space)
 */
int ac_circ_buf_pushm(ac_circ_buf_t *cbuf, void *buf, size_t count)
{
	if (circ_space_to_end(cbuf) < count)
		return -1;

	memcpy(cbuf->buf + cbuf->head, buf, count * sizeof(void *));
	cbuf->head = (cbuf->head + count) & (cbuf->size - 1);

	return 0;
}

/**
 * ac_circ_buf_push - push an item into the buffer
 *
 * @cbuf: The circular buffer to work on
 * @buf: The item to add
 *
 * Returns:
 *
 * 0 on success or -1 if the buffer is full
 */
int ac_circ_buf_push(ac_circ_buf_t *cbuf, void *buf)
{
	if (circ_space(cbuf) == 0)
		return -1;

	cbuf->buf[cbuf->head] = buf;
	cbuf->head = (cbuf->head + 1) & (cbuf->size - 1);

	return 0;
}

/**
 * ac_circ_buf_popm - pop multiple items from buffer
 *
 * @cbuf: The circular buffer to work on
 * @count: The number of items to pop from the buffer
 *
 * Returns:
 *
{'fraction_non_alphanumeric': 0.1393689551292215, 'fraction_numerical': 0.014586966862216584, 'mean_word_length': 3.3353951890034366, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 71, 'https://': 2, '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': '6298075', 'n_tokens_mistral': 2522, 'n_tokens_neox': 2419, 'n_words': 740}