several performance tweaks 542c58d8
anselm@anselm1 · 2008-03-22 14:52 2 file(s) · +44 −19
Makefile +1 −1
1 1
# dmenu - dynamic menu
2 -
# © 2006-2007 Anselm R. Garbe, Sander van Dijk
2 +
# See LICENSE file for copyright and license details.
3 3
4 4
include config.mk
5 5
dmenu.c +43 −18
35 35
typedef struct Item Item;
36 36
struct Item {
37 37
	char *text;
38 -
	Bool matched;
39 38
	Item *next;		/* traverses all items */
40 39
	Item *left, *right;	/* traverses items matching current search pattern */
41 40
};
42 41
43 42
/* forward declarations */
44 -
Item *appenditem(Item *i, Item *last);
43 +
void appenditem(Item *i, Item **list, Item **last);
45 44
void calcoffsets(void);
46 45
char *cistrstr(const char *s, const char *sub);
47 46
void cleanup(void);
92 91
int (*fstrncmp)(const char *, const char *, size_t n) = strncmp;
93 92
char *(*fstrstr)(const char *, const char *) = strstr;
94 93
95 -
Item *
96 -
appenditem(Item *i, Item *last) {
97 -
	if(!last)
98 -
		item = i;
94 +
void
95 +
appenditem(Item *i, Item **list, Item **last) {
96 +
	if(!(*last))
97 +
		*list = i;
99 98
	else
100 -
		last->right = i;
101 -
	i->left = last;
99 +
		(*last)->right = i;
100 +
	i->left = *last;
102 101
	i->right = NULL;
103 -
	last = i;
104 -
	nitem++;
105 -
	return last;
102 +
	*last = i;
106 103
}
107 104
108 105
void
521 518
void
522 519
match(char *pattern) {
523 520
	unsigned int plen;
524 -
	Item *i, *j;
521 +
	Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend;
525 522
526 523
	if(!pattern)
527 524
		return;
528 525
	plen = strlen(pattern);
529 -
	item = j = NULL;
526 +
	item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL;
530 527
	nitem = 0;
531 528
	for(i = allitems; i; i = i->next)
532 -
		if((i->matched = !fstrncmp(pattern, i->text, plen)))
533 -
			j = appenditem(i, j);
534 -
	for(i = allitems; i; i = i->next)
535 -
		if(!i->matched && fstrstr(i->text, pattern))
536 -
			j = appenditem(i, j);
529 +
		if(!fstrncmp(pattern, i->text, plen + 1)) {
530 +
			appenditem(i, &lexact, &exactend);
531 +
			nitem++;
532 +
		}
533 +
		else if(!fstrncmp(pattern, i->text, plen)) {
534 +
			appenditem(i, &lprefix, &prefixend);
535 +
			nitem++;
536 +
		}
537 +
		else if(fstrstr(i->text, pattern)) {
538 +
			appenditem(i, &lsubstr, &substrend);
539 +
			nitem++;
540 +
		}
541 +
	if(lexact) {
542 +
		item = lexact;
543 +
		itemend = exactend;
544 +
	}
545 +
	if(lprefix) {
546 +
		if(itemend) {
547 +
			itemend->right - lprefix;
548 +
			lprefix->left = itemend;
549 +
		}
550 +
		else
551 +
			item = lprefix;
552 +
		itemend = prefixend;
553 +
	}
554 +
	if(lsubstr) {
555 +
		if(itemend) {
556 +
			itemend->right = lsubstr;
557 +
			lsubstr->left = itemend;
558 +
		}
559 +
		else
560 +
			item = lsubstr;
561 +
	}
537 562
	curr = prev = next = sel = item;
538 563
	calcoffsets();
539 564
}