
/*
 *  MEMORY.C
 *
 *  (c)Copyright 1987 Matthew Dillon, All Rights Reserved.
 *
 */

#include "files.h"

#define BLKSIZE     256     /*	# of records to allocate at once	*/
#define STRBLKSIZE  4096
#define MAXSTRLEN   64	    /*	maximum string len for cached strings	*/

static RECORD *Freelist;
static RECORD *Blk;
static short  Bi;
static char   *Strs[MAXSTRLEN];
static char   *Sbuf;
static short  Si;

RECORD *
allocrecord()
{
    register RECORD *rec;
    if (rec = Freelist) {
	Freelist = Freelist->next;
	return(rec);
    }
    if (!Bi) {
	Blk = (RECORD *)malloc(sizeof(RECORD) * BLKSIZE);
	if (!Blk)
	    return(NULL);
	Bi = 256;
    }
    --Bi;
    return(Blk++);
}

void
freerecord(rec)
RECORD *rec;
{
    rec->next = Freelist;
    Freelist = rec;
}

char *
allocstr(str)
char *str;
{
    register short bytes = strlen(str) + 1;
    register char *ptr;

    if (bytes >= 4 && bytes < MAXSTRLEN) {
	if (Strs[bytes]) {
	    ptr = Strs[bytes];
	    Strs[bytes] = *(char **)ptr;
	} else {
	    bytes = (bytes + 1) & ~1;
	    if (Si < bytes) {
		Sbuf = malloc(STRBLKSIZE);
		if (!Sbuf)
		    return(NULL);
		Si = STRBLKSIZE;
	    }
	    ptr = Sbuf;
	    Sbuf += bytes;
	    Si -= bytes;
	}
    } else {
	ptr = malloc(bytes);
	if (!ptr)
	    return(NULL);
    }
    strcpy(ptr, str);
    return(ptr);
}

void
freestr(ptr)
char *ptr;
{
    register short len;

    if (ptr) {
	len = strlen(ptr) + 1;
	if (len >= 4 && len < MAXSTRLEN) {
	    *(char **)ptr = Strs[len];
	    Strs[len] = ptr;
	} else {
	    free(ptr);
	}
    }
}

