buffer changes

This commit is contained in:
bronku 2025-11-13 18:30:36 +01:00
parent 1d1d440cb9
commit 746fc01323

View file

@ -1,145 +1,65 @@
#pragma once #pragma once
#include "record.hpp" #include "record.hpp"
#include <algorithm> #include <stdexcept>
#include <iostream>
#include <vector> #include <vector>
// Main buffer pool - owns all memory class Buffer;
class BufferPool {
class SubBuffer {
private: private:
std::vector<Record> storage; Record* data_;
int buffer_capacity; size_t size_;
int num_buffers;
friend class Buffer;
SubBuffer(Record* data, size_t size)
: data_(data)
, size_(size)
{
}
public: public:
BufferPool(int num_buffers, int buffer_capacity) // for std::sort support
: storage(num_buffers * buffer_capacity) using iterator = Record*;
, buffer_capacity(buffer_capacity) iterator begin() { return data_; }
, num_buffers(num_buffers) iterator end() { return data_ + size_; }
Record& operator[](size_t index)
{ {
return data_[index];
} }
Record* get_buffer_ptr(int index) size_t size() const { return size_; }
{
return storage.data() + (index * buffer_capacity);
}
int get_buffer_capacity() const { return buffer_capacity; }
int get_num_buffers() const { return num_buffers; }
int total_capacity() const { return storage.size(); }
// Sort entire pool (for stage 1 - creating runs)
void sort_all(int count)
{
std::sort(storage.begin(), storage.begin() + count);
}
}; };
// View into a section of the buffer pool class Buffer {
class BufferView {
private: private:
Record* data; std::vector<Record> storage_;
int capacity;
int length;
public: public:
BufferView(Record* ptr, int cap) explicit Buffer(size_t total_size)
: data(ptr) : storage_(total_size)
, capacity(cap)
, length(0)
{ {
} }
// Read up to capacity records from stream std::vector<SubBuffer> divide(size_t n)
int read_from(std::istream& in)
{ {
length = 0; if (n == 0) {
for (int i = 0; i < capacity; i++) { throw std::invalid_argument("Cannot divide buffer into 0 pieces");
if (!(in >> data[i])) {
break;
}
length++;
}
return length;
} }
// Write all current records to stream size_t total_size = storage_.size();
bool write_to(std::ostream& out) const if (total_size % n != 0) {
{ throw std::invalid_argument("Size not divisible by n");
for (int i = 0; i < length; i++) {
out << data[i] << '\n';
if (!out)
return false;
}
return true;
} }
// For stage 2: peek at front record without consuming std::vector<SubBuffer> result(n);
const Record& front() const { return data[0]; } size_t piece_size = total_size / n;
for (size_t i = 0; i < n; ++i) {
// For stage 2: consume the front record result[i] = SubBuffer(storage_.data() + i * piece_size, piece_size);
void pop_front()
{
if (length > 0) {
for (int i = 0; i < length - 1; i++) {
data[i] = data[i + 1];
}
length--;
}
} }
// Refill from stream when buffer becomes empty during merge return result;
bool refill_from(std::istream& in)
{
return read_from(in) > 0;
} }
int size() const { return length; }
int get_capacity() const { return capacity; }
bool empty() const { return length == 0; }
bool full() const { return length == capacity; }
Record& operator[](int i) { return data[i]; }
const Record& operator[](int i) const { return data[i]; }
};
// For output buffer during merge
class OutputBuffer {
private:
Record* data;
int capacity;
int length;
public:
OutputBuffer(Record* ptr, int cap)
: data(ptr)
, capacity(cap)
, length(0)
{
}
// Add record to output buffer
bool add(const Record& rec)
{
if (length >= capacity) {
return false; // Buffer full
}
data[length++] = rec;
return true;
}
// Flush buffer to stream and reset
bool flush_to(std::ostream& out)
{
for (int i = 0; i < length; i++) {
out << data[i] << '\n';
if (!out)
return false;
}
length = 0;
return true;
}
bool full() const { return length >= capacity; }
int size() const { return length; }
}; };