uniq: optimization: reuse the prevline buffer
don't strdup for each prevline, try to reuse the allocated buffer and if needed increase it's size.
This commit is contained in:
parent
603499b674
commit
78187474cf
41
uniq.c
41
uniq.c
|
@ -15,11 +15,12 @@ static int sskip = 0;
|
||||||
static char *prevline = NULL;
|
static char *prevline = NULL;
|
||||||
static char *prevoffset = NULL;
|
static char *prevoffset = NULL;
|
||||||
static long prevlinecount = 0;
|
static long prevlinecount = 0;
|
||||||
|
static size_t prevlinesiz = 0;
|
||||||
|
|
||||||
static char *
|
static const char *
|
||||||
uniqskip(char *l)
|
uniqskip(const char *l)
|
||||||
{
|
{
|
||||||
char *lo = l;
|
const char *lo = l;
|
||||||
int f = fskip, s = sskip;
|
int f = fskip, s = sskip;
|
||||||
|
|
||||||
for (; f; --f) {
|
for (; f; --f) {
|
||||||
|
@ -33,34 +34,37 @@ uniqskip(char *l)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uniqline(FILE *ofp, char *l)
|
uniqline(FILE *ofp, const char *l, size_t len)
|
||||||
{
|
{
|
||||||
char *loffset = l ? uniqskip(l) : l;
|
const char *loffset = l ? uniqskip(l) : l;
|
||||||
|
|
||||||
int linesequel = (!l || !prevline)
|
int linesequel = l && prevoffset &&
|
||||||
? l == prevline
|
!strcmp(loffset, prevoffset);
|
||||||
: !strcmp(loffset, prevoffset);
|
|
||||||
|
|
||||||
if (linesequel) {
|
if (linesequel) {
|
||||||
++prevlinecount;
|
++prevlinecount;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevline) {
|
if (prevoffset) {
|
||||||
if ((prevlinecount == 1 && !dflag) ||
|
if ((prevlinecount == 1 && !dflag) ||
|
||||||
(prevlinecount != 1 && !uflag)) {
|
(prevlinecount != 1 && !uflag)) {
|
||||||
if (*countfmt)
|
if (*countfmt)
|
||||||
fprintf(ofp, countfmt, prevlinecount);
|
fprintf(ofp, countfmt, prevlinecount);
|
||||||
fputs(prevline, ofp);
|
fputs(prevline, ofp);
|
||||||
}
|
}
|
||||||
free(prevline);
|
prevoffset = NULL;
|
||||||
prevline = prevoffset = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l) {
|
if (l) {
|
||||||
prevline = estrdup(l);
|
if (!prevline || len >= prevlinesiz) {
|
||||||
prevoffset = prevline + (loffset - l);
|
prevlinesiz = len + 1;
|
||||||
}
|
prevline = erealloc(prevline, prevlinesiz);
|
||||||
|
}
|
||||||
|
memcpy(prevline, l, len);
|
||||||
|
prevline[len] = '\0';
|
||||||
|
prevoffset = prevline + (loffset - l);
|
||||||
|
}
|
||||||
prevlinecount = 1;
|
prevlinecount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,15 +73,16 @@ uniq(FILE *fp, FILE *ofp)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
while (getline(&buf, &size, fp) != -1)
|
while ((len = getline(&buf, &size, fp)) != -1)
|
||||||
uniqline(ofp, buf);
|
uniqline(ofp, buf, (size_t)len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uniqfinish(FILE *ofp)
|
uniqfinish(FILE *ofp)
|
||||||
{
|
{
|
||||||
uniqline(ofp, NULL);
|
uniqline(ofp, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue
Block a user