<commit_before>#ifndef AFT_BACKEND_LINUX_USB_BUFFERALLOCATOR_H
#define AFT_BACKEND_LINUX_USB_BUFFERALLOCATOR_H

#include <mtp/ByteArray.h>
#include <mtp/types.h>
#include <mtp/log.h>
#include <Exception.h>
#include <sys/mman.h>
#include <unistd.h>

namespace mtp { namespace usb
{
	struct IBuffer
	{
		virtual ~IBuffer() { }

		virtual u8 * GetData() = 0;
		virtual size_t GetSize() = 0;
	};
	DECLARE_PTR(IBuffer);

	class ByteArrayBuffer : private ByteArray, public IBuffer
	{
	public:
		ByteArrayBuffer(size_t size): ByteArray(size)
		{ }

		~ByteArrayBuffer()
		{ }

		virtual u8 * GetData() override
		{ return data(); }
		virtual size_t GetSize() override
		{ return size(); }
	};

	class MappedBuffer : public IBuffer
	{
		u8 *		_data;
		size_t		_size;

	public:
		MappedBuffer(u8 *data, size_t size): _data(data), _size(size)
		{ }
		virtual u8 * GetData() override
		{ return _data; }
		virtual size_t GetSize() override
		{ return _size; }
	};
	using MappedBufferWeakPtr = std::weak_ptr<MappedBuffer>;
	DECLARE_PTR(MappedBuffer);

	class BufferAllocator
	{
		static constexpr size_t Buffers = 2;

		int			_fd;
		long		_pageSize;
		u8 *		_buffer;
		size_t		_bufferSize;

		std::array<MappedBufferWeakPtr, Buffers> _buffers;

	public:
		BufferAllocator(int fd): _fd(fd), _pageSize(sysconf(_SC_PAGESIZE)), _buffer(nullptr), _bufferSize(0)
		{
			if (_pageSize <= 0)
				throw posix::Exception("sysconf(_SC_PAGESIZE)");
			debug("page size = ", _pageSize);
		}

		IBufferPtr Allocate(size_t size)
		{
			//if (_fd < 0)
				return std::make_shared<ByteArrayBuffer>(size);

			if (!_buffer)
			{
				_bufferSize = (size + _pageSize - 1) / _pageSize * _pageSize;
				try
				{
					auto buffer = static_cast<u8 *>(mmap(nullptr, _bufferSize * Buffers, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0));<commit_msg>enabled zerocopy allocator if it's available<commit_after>#ifndef AFT_BACKEND_LINUX_USB_BUFFERALLOCATOR_H
#define AFT_BACKEND_LINUX_USB_BUFFERALLOCATOR_H

#include <mtp/ByteArray.h>
#include <mtp/types.h>
#include <mtp/log.h>
#include <Exception.h>
#include <sys/mman.h>
#include <unistd.h>

namespace mtp { namespace usb
{
	struct IBuffer
	{
		virtual ~IBuffer() { }

		virtual u8 * GetData() = 0;
		virtual size_t GetSize() = 0;
	};
	DECLARE_PTR(IBuffer);

	class ByteArrayBuffer : private ByteArray, public IBuffer
	{
	public:
		ByteArrayBuffer(size_t size): ByteArray(size)
		{ }

		~ByteArrayBuffer()
		{ }

		virtual u8 * GetData() override
		{ return data(); }
		virtual size_t GetSize() override
		{ return size(); }
	};

	class MappedBuffer : public IBuffer
	{
		u8 *		_data;
		size_t		_size;

	public:
		MappedBuffer(u8 *data, size_t size): _data(data), _size(size)
		{ }
		virtual u8 * GetData() override
		{ return _data; }
		virtual size_t GetSize() override
		{ return _size; }
	};
	using MappedBufferWeakPtr = std::weak_ptr<MappedBuffer>;
	DECLARE_PTR(MappedBuffer);

	class BufferAllocator
	{
		static constexpr size_t Buffers = 2;

		int			_fd;
		long		_pageSize;
		u8 *		_buffer;
		size_t		_bufferSize;

		std::array<MappedBufferWeakPtr, Buffers> _buffers;

	public:
		BufferAllocator(int fd): _fd(fd), _pageSize(sysconf(_SC_PAGESIZE)), _buffer(nullptr), _bufferSize(0)
		{
			if (_pageSize <= 0)
				throw posix::Exception("sysconf(_SC_PAGESIZE)");
			debug("page size = ", _pageSize);
		}

		IBufferPtr Allocate(size_t size)
		{
			if (_fd < 0)
				return std::make_shared<ByteArrayBuffer>(size);

			if (!_buffer)
			{
				_bufferSize = (size + _pageSize - 1) / _pageSize * _pageSize;
				try
				{
					auto buffer = static_cast<u8 *>(mmap(nullptr, _bufferSize * Buffers, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0));
{'fraction_non_alphanumeric': 0.1230474102493834, 'fraction_numerical': 0.00822143052891203, 'mean_word_length': 4.155367231638418, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 23, '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': '3855554', 'n_tokens_mistral': 1561, 'n_tokens_neox': 1387, 'n_words': 300}