Skip to content

Commit

Permalink
buffer: make indexOf faster
Browse files Browse the repository at this point in the history
Improve the performance of IndexOf() for Buffer#indexOf() searches.
  • Loading branch information
trevnorris committed Mar 4, 2015
1 parent 78581c8 commit e3cdaab
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
36 changes: 30 additions & 6 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -607,13 +607,37 @@ int32_t IndexOf(const char* haystack,
const char* needle,
size_t n_length) {
CHECK_GE(h_length, n_length);
// TODO(trevnorris): Implement Boyer-Moore string search algorithm.
for (size_t i = 0; i < h_length - n_length + 1; i++) {
if (haystack[i] == needle[0]) {
if (memcmp(haystack + i, needle, n_length) == 0)
return i;
}

const char* inc;
const void* ptr;

// Guard against zero length searches
if (h_length == 0 || n_length == 0 || n_length > h_length)
return -1;

// Single character case
if (n_length == 1) {
ptr = memchr(haystack, *needle, h_length);
if (ptr == nullptr)
return -1;
return static_cast<int32_t>(static_cast<const char*>(ptr) - haystack);
}

// Do multicharacter string match
inc = haystack;
do {
ptr = memchr(inc, *needle, h_length - static_cast<int32_t>(inc - haystack));
if (ptr != nullptr) {
const void* ptr2 = memmem(inc,
h_length - static_cast<int32_t>(inc - haystack),
needle,
n_length);
if (ptr2 != nullptr)
return static_cast<int32_t>(static_cast<const char*>(ptr2) - haystack);
inc = static_cast<const char*>(ptr);
}
} while (ptr != nullptr);

return -1;
}

Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-buffer-indexof.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ assert.equal(b.indexOf('bc', -5), 1);
assert.equal(b.indexOf('bc', NaN), 1);
assert.equal(b.indexOf('bc', -Infinity), 1);
assert.equal(b.indexOf('bc', Infinity), -1);
assert.equal(b.indexOf('cd'), 2);
assert.equal(b.indexOf('f'), b.length - 1);
assert.equal(b.indexOf('z'), -1);
assert.equal(b.indexOf(''), -1);
Expand Down

0 comments on commit e3cdaab

Please sign in to comment.