mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-22 00:06:06 +08:00
Optimize QueryResultSet so offset lookups are O[1] after initial scan
This commit is contained in:
parent
32ccaad1e7
commit
b043c30565
|
@ -30,6 +30,7 @@ class MutableQueryResultSet extends QueryResultSet
|
|||
|
||||
models = @models()
|
||||
@_modelsHash = {}
|
||||
@_idToIndexHash = null
|
||||
@replaceModel(m) for m in models
|
||||
|
||||
addModelsInRange: (rangeModels, range) ->
|
||||
|
@ -39,6 +40,7 @@ class MutableQueryResultSet extends QueryResultSet
|
|||
addIdsInRange: (rangeIds, range) ->
|
||||
if @_offset is null or range.isInfinite()
|
||||
@_ids = rangeIds
|
||||
@_idToIndexHash = null
|
||||
@_offset = range.offset
|
||||
else
|
||||
currentEnd = @_offset + @_ids.length
|
||||
|
@ -58,18 +60,21 @@ class MutableQueryResultSet extends QueryResultSet
|
|||
existingAfter = @_ids.slice(rangeIdsEnd - @_offset)
|
||||
|
||||
@_ids = [].concat(existingBefore, rangeIds, existingAfter)
|
||||
@_idToIndexHash = null
|
||||
@_offset = Math.min(@_offset, range.offset)
|
||||
|
||||
replaceModel: (item) ->
|
||||
return unless item
|
||||
@_modelsHash[item.clientId] = item
|
||||
@_modelsHash[item.id] = item
|
||||
@_idToIndexHash = null
|
||||
|
||||
removeModelAtOffset: (item, offset) ->
|
||||
idx = offset - @_offset
|
||||
delete @_modelsHash[item.clientId]
|
||||
delete @_modelsHash[item.id]
|
||||
@_ids.splice(idx, 1)
|
||||
@_idToIndexHash = null
|
||||
|
||||
setQuery: (query) ->
|
||||
@_query = query.clone()
|
||||
|
|
|
@ -31,6 +31,7 @@ class QueryResultSet
|
|||
throw new Error("setByApplyingModels: A hash of models is required.")
|
||||
set = set.clone()
|
||||
set._modelsHash = models
|
||||
set._idToIndexHash = null
|
||||
set
|
||||
|
||||
constructor: (other = {}) ->
|
||||
|
@ -38,11 +39,13 @@ class QueryResultSet
|
|||
@_offset = other._offset ? null
|
||||
@_query = other._query ? null
|
||||
@_ids = other._ids ? []
|
||||
@_idToIndexHash = other._idToIndexHash ? null
|
||||
|
||||
clone: ->
|
||||
new @constructor({
|
||||
_ids: [].concat(@_ids)
|
||||
_modelsHash: _.extend({}, @_modelsHash)
|
||||
_idToIndexHash: _.extend({}, @_idToIndexHash)
|
||||
_query: @_query
|
||||
_offset: @_offset
|
||||
})
|
||||
|
@ -82,15 +85,20 @@ class QueryResultSet
|
|||
modelWithId: (id) ->
|
||||
@_modelsHash[id]
|
||||
|
||||
buildIdToIndexHash: ->
|
||||
@_idToIndexHash = {}
|
||||
for id, idx in @_ids
|
||||
@_idToIndexHash[id] = idx
|
||||
model = @_modelsHash[id]
|
||||
@_idToIndexHash[model.clientId] = idx if model
|
||||
|
||||
offsetOfId: (id) ->
|
||||
idx = @_ids.indexOf(id)
|
||||
if @_idToIndexHash is null
|
||||
@buildIdToIndexHash()
|
||||
|
||||
# If we can't find the item, try to match against client ids as well. Some
|
||||
# items in the models() array may not be loaded, but we can try our best.
|
||||
if idx is -1
|
||||
idx = _.findIndex @models(), (m) -> m and (m.id is id or m.clientId is id)
|
||||
|
||||
return -1 if idx is -1
|
||||
return @_offset + idx
|
||||
if @_idToIndexHash[id]
|
||||
return @_idToIndexHash[id] + @_offset
|
||||
else
|
||||
return -1
|
||||
|
||||
module.exports = QueryResultSet
|
||||
|
|
Loading…
Reference in a new issue