mirror of
git://git.sv.gnu.org/nano.git
synced 2025-03-06 08:41:28 +03:00
input: allocate a small keystroke buffer, and never free it
Instead of allocating and freeing a tiny fragment of memory for every keystroke, reserve a small piece in the beginning and then retain it, because it will be needed again and again and again. Increase the size when needed (for a large paste, probably), but don't bother to shrink it afterward. This addresses the first part of https://savannah.gnu.org/bugs/?63086.
This commit is contained in:
parent
0d1438a731
commit
3922b531a8
@ -581,6 +581,7 @@ linestruct *line_from_number(ssize_t number);
|
||||
/* Most functions in winio.c. */
|
||||
void record_macro(void);
|
||||
void run_macro(void);
|
||||
void reserve_space_for(size_t newsize);
|
||||
size_t waiting_keycodes(void);
|
||||
#ifdef ENABLE_NANORC
|
||||
void implant(const char *string);
|
||||
|
32
src/winio.c
32
src/winio.c
@ -46,6 +46,8 @@ static int *key_buffer = NULL;
|
||||
/* A buffer for the keystrokes that haven't been handled yet. */
|
||||
static int *nextcodes = NULL;
|
||||
/* A pointer pointing at the next keycode in the keystroke buffer. */
|
||||
static size_t capacity = 32;
|
||||
/* The size of the keystroke buffer; gets doubled whenever needed. */
|
||||
static size_t waiting_codes = 0;
|
||||
/* The number of key codes waiting in the keystroke buffer. */
|
||||
#ifdef ENABLE_NANORC
|
||||
@ -126,7 +128,8 @@ void run_macro(void)
|
||||
return;
|
||||
}
|
||||
|
||||
key_buffer = nrealloc(key_buffer, macro_length * sizeof(int));
|
||||
if (macro_length > capacity)
|
||||
reserve_space_for(macro_length);
|
||||
|
||||
for (size_t i = 0; i < macro_length; i++)
|
||||
key_buffer[i] = macro_buffer[i];
|
||||
@ -137,6 +140,14 @@ void run_macro(void)
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Allocate the requested space for the keystroke buffer. */
|
||||
void reserve_space_for(size_t newsize)
|
||||
{
|
||||
key_buffer = nrealloc(key_buffer, newsize * sizeof(int));
|
||||
nextcodes = key_buffer;
|
||||
capacity = newsize;
|
||||
}
|
||||
|
||||
/* Control character compatibility:
|
||||
*
|
||||
* - Ctrl-H is Backspace under ASCII, ANSI, VT100, and VT220.
|
||||
@ -246,8 +257,10 @@ void read_keys_from(WINDOW *frame)
|
||||
|
||||
curs_set(0);
|
||||
|
||||
/* Initiate the keystroke buffer, and save the keycode in it. */
|
||||
key_buffer = nrealloc(key_buffer, sizeof(int));
|
||||
/* When there is no keystroke buffer yet, allocate one. */
|
||||
if (!key_buffer)
|
||||
reserve_space_for(capacity);
|
||||
|
||||
key_buffer[0] = input;
|
||||
|
||||
nextcodes = key_buffer;
|
||||
@ -284,10 +297,11 @@ void read_keys_from(WINDOW *frame)
|
||||
if (input == ERR)
|
||||
break;
|
||||
|
||||
/* Extend the keystroke buffer, and save the keycode at its end. */
|
||||
key_buffer = nrealloc(key_buffer, ++waiting_codes * sizeof(int));
|
||||
key_buffer[waiting_codes - 1] = input;
|
||||
nextcodes = key_buffer;
|
||||
/* When the keystroke buffer is full, extend it. */
|
||||
if (waiting_codes == capacity)
|
||||
reserve_space_for(2 * capacity);
|
||||
|
||||
key_buffer[waiting_codes++] = input;
|
||||
}
|
||||
|
||||
/* Restore blocking-input mode. */
|
||||
@ -316,9 +330,9 @@ void put_back(int keycode)
|
||||
|
||||
/* If there is no room at the head of the keystroke buffer, make room. */
|
||||
if (nextcodes == key_buffer) {
|
||||
key_buffer = nrealloc(key_buffer, (waiting_codes + 1) * sizeof(int));
|
||||
if (waiting_codes == capacity)
|
||||
reserve_space_for(2 * capacity);
|
||||
memmove(key_buffer + 1, key_buffer, waiting_codes * sizeof(int));
|
||||
nextcodes = key_buffer;
|
||||
} else
|
||||
nextcodes--;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user