Skip to content

Commit

Permalink
Use native indexOf whenever possible
Browse files Browse the repository at this point in the history
This uses a windowing approach to determine how much of a buffer can be searched by the native indexOf when searching. It falls back to JS when it hits a boundary and if there is no available native search window. I'm pretty sure a BufferList can't be searched drastically faster than this.

Actual performance needs to be measured.
  • Loading branch information
reconbot committed Oct 5, 2018
1 parent 8c596a8 commit b254662
Show file tree
Hide file tree
Showing 3 changed files with 500 additions and 488 deletions.
72 changes: 34 additions & 38 deletions bl.js
Expand Up @@ -274,8 +274,9 @@ BufferList.prototype.indexOf = function (search, offset, encoding) {
search = Buffer.from(search, encoding)
} else if (!search instanceof BufferList && !Buffer.isBuffer(search)) {
search = Buffer.from(search)
} else {
search = new BufferList(search).slice()
}
search = new BufferList(search)

offset = Number(offset || 0)
if (isNaN(offset)) {
Expand All @@ -294,49 +295,44 @@ BufferList.prototype.indexOf = function (search, offset, encoding) {
return offset > this.length ? this.length : offset
}

// Use the native buffer indexOf
if (search.length === 1) {
const searchBuffer = search.slice()
const blOffset = this._offset(offset)
let blIndex = blOffset[0]
let buffOffset = blOffset[1]

for (blIndex; blIndex < this._bufs.length; blIndex++) {
let position = this._bufs[blIndex].indexOf(searchBuffer, buffOffset)
if (position !== -1) {
return this._reverseOffset([blIndex, position])
const blOffset = this._offset(offset)
let blIndex = blOffset[0] // index of which internal buffer we're working on
let buffOffset = blOffset[1] // offset of the internal buffer we're working on

// scan over each buffer
for (blIndex; blIndex < this._bufs.length; blIndex++) {
const buff = this._bufs[blIndex]
while(buffOffset < buff.length) {
const availableWindow = buff.length - buffOffset
if (availableWindow >= search.length) {
const nativeSearchResult = buff.indexOf(search, buffOffset)
if (nativeSearchResult !== -1) {
return this._reverseOffset([blIndex, nativeSearchResult])
}
buffOffset = buff.length - search.length + 1 // end of native search window
} else {
const revOffset = this._reverseOffset([blIndex, buffOffset])
if (this._match(revOffset, search)) {
return revOffset
}
buffOffset++
}
buffOffset = 0
}
return -1
buffOffset = 0
}
return -1
}


let searchOffset = 0
let searchPosition = -1

for (let blSearchOffset = offset; blSearchOffset < this.length ; ++blSearchOffset) {
if(this.get(blSearchOffset) != search.get(searchOffset)){
searchPosition = -1
blSearchOffset -= searchOffset-1
searchOffset = 0
}

if(this.get(blSearchOffset) == search.get(searchOffset)) {
if(searchPosition == -1) {
searchPosition = blSearchOffset
}
++searchOffset
if(searchOffset == search.length) {
break
}
}
BufferList.prototype._match = function(offset, search) {
if (this.length - offset < search.length) {
return false
}

if (searchPosition > -1 && this.length - searchPosition < search.length) {
return -1
for (let searchOffset = 0; searchOffset < search.length ; searchOffset++) {
if(this.get(offset + searchOffset) !== search[searchOffset]){
return false
}
}
return searchPosition
return true
}


Expand Down

0 comments on commit b254662

Please sign in to comment.