24#include "BlockArray.h"
32using namespace Konsole;
34BlockArray::BlockArray()
39 , lastmap_index(size_t(-1))
46 blocksize = ((
sizeof(Block) / getpagesize()) + 1) * getpagesize();
50BlockArray::~BlockArray()
56size_t BlockArray::append(Block *block)
63 if (current >= size) {
68 rc = lseek(ion, current * blocksize, SEEK_SET);
70 perror(
"HistoryBuffer::add.seek");
74 rc = write(ion, block, blocksize);
76 perror(
"HistoryBuffer::add.write");
92size_t BlockArray::newBlock()
99 lastblock =
new Block();
103Block *BlockArray::lastBlock()
const
108bool BlockArray::has(
size_t i)
const
110 if (i == index + 1) {
117 if (index - i >= length) {
123const Block *BlockArray::at(
size_t i)
125 if (i == index + 1) {
129 if (i == lastmap_index) {
134 qDebug() <<
"BlockArray::at() i > index\n";
143 Block *block = (Block *)mmap(
nullptr, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
145 if (block == (Block *)-1) {
156void BlockArray::unmap()
159 int res = munmap((
char *)lastmap, blocksize);
165 lastmap_index = size_t(-1);
168bool BlockArray::setSize(
size_t newsize)
170 return setHistorySize(newsize * 1024 / blocksize);
173bool BlockArray::setHistorySize(
size_t newsize)
175 if (size == newsize) {
188 current = size_t(-1);
193 FILE *tmp = tmpfile();
195 perror(
"konsole: cannot open temp file.\n");
197 ion = dup(fileno(tmp));
199 perror(
"konsole: cannot dup temp file.\n");
207 Q_ASSERT(!lastblock);
209 lastblock =
new Block();
214 if (newsize > size) {
219 decreaseBuffer(newsize);
220 ftruncate(ion, length * blocksize);
227void BlockArray::moveBlock(FILE *fion,
int cursor,
int newpos,
char *buffer2)
229 int res = fseek(fion, cursor * blocksize, SEEK_SET);
233 res = fread(buffer2, blocksize, 1, fion);
238 res = fseek(fion, newpos * blocksize, SEEK_SET);
242 res = fwrite(buffer2, blocksize, 1, fion);
249void BlockArray::decreaseBuffer(
size_t newsize)
251 if (index < newsize) {
255 int offset = (current - (newsize - 1) + size) % size;
262 char *buffer1 =
new char[blocksize];
264 FILE *fion = fdopen(dup(ion),
"w+b");
267 perror(
"fdopen/dup");
272 if (current <= newsize) {
273 firstblock = current + 1;
279 for (
size_t i = 0, cursor = firstblock; i < newsize; i++) {
280 oldpos = (size + cursor + offset) % size;
281 moveBlock(fion, oldpos, cursor, buffer1);
282 if (oldpos < newsize) {
289 current = newsize - 1;
297void BlockArray::increaseBuffer()
303 int offset = (current + size + 1) % size;
309 char *buffer1 =
new char[blocksize];
310 char *buffer2 =
new char[blocksize];
315 if (size % offset == 0) {
320 FILE *fion = fdopen(dup(ion),
"w+b");
322 perror(
"fdopen/dup");
329 for (
int i = 0; i < runs; i++) {
331 int firstblock = (offset + i) % size;
332 res = fseek(fion, firstblock * blocksize, SEEK_SET);
336 res = fread(buffer1, blocksize, 1, fion);
341 for (
int j = 1, cursor = firstblock; j < bpr; j++) {
342 cursor = (cursor + offset) % size;
343 newpos = (cursor - offset + size) % size;
344 moveBlock(fion, cursor, newpos, buffer2);
346 res = fseek(fion, i * blocksize, SEEK_SET);
350 res = fwrite(buffer1, blocksize, 1, fion);