Proposed patch; I'll write a ChangeLog entry if it's accepted. By defining delta and next as pointers to arrays, we can avoid copying by not having an intermediate array when kwset->trans is NULL.
There may be a downside in using a variable pointer instead of an array name (which is equivalent to a constant pointer) when first writing to the region to which it points. I haven't benchmarked to check, and I wouldn't have access to a variety of architectures on which to do so anyway. What do you think? --- src/kwset.c 2005-07-04 01:14:37 -0400 +++ src/kwset.c 2005-07-04 09:39:09 -0400 @@ -383,6 +383,6 @@ kwsprep (kwset_t kws) register int i; register struct trie *curr; register char const *trans; - unsigned char delta[NCHAR]; + unsigned char our_delta[NCHAR], *delta; kwset = (struct kwset *) kws; @@ -390,6 +390,7 @@ kwsprep (kwset_t kws) /* Initial values for the delta table; will be changed later. The delta entry for a given character is the smallest depth of any node at which an outgoing edge is labeled by that character. */ + delta = kwset->trans ? our_delta : kwset->delta; memset(delta, kwset->mind < UCHAR_MAX ? kwset->mind : UCHAR_MAX, NCHAR); /* Check if we can use the simple boyer-moore algorithm, instead @@ -419,7 +420,7 @@ kwsprep (kwset_t kws) else { register struct trie *fail; - struct trie *last, *next[NCHAR]; + struct trie *last, *our_next[NCHAR], **next; /* Traverse the nodes of the trie in level order, simultaneously computing the delta table, failure function, and shift function. */ @@ -468,23 +469,20 @@ kwsprep (kwset_t kws) /* Create a vector, indexed by character code, of the outgoing links from the root node. */ + next = kwset->trans ? our_next : kwset->next; for (i = 0; i < NCHAR; ++i) next[i] = NULL; treenext(kwset->trie->links, next); if ((trans = kwset->trans) != NULL) for (i = 0; i < NCHAR; ++i) - kwset->next[i] = next[U(trans[i])]; - else - memcpy(kwset->next, next, NCHAR * sizeof(struct trie *)); + kwset->next[i] = our_next[U(trans[i])]; } /* Fix things up for any translation table. */ if ((trans = kwset->trans) != NULL) for (i = 0; i < NCHAR; ++i) - kwset->delta[i] = delta[U(trans[i])]; - else - memcpy(kwset->delta, delta, NCHAR); + kwset->delta[i] = our_delta[U(trans[i])]; return NULL; }