converted marks.js to sparse list...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2014-01-16 06:36:59 +04:00
parent a76753eaa5
commit 6fe9276cee
4 changed files with 83 additions and 62 deletions

View File

@ -110,6 +110,22 @@ Roadmap
[_] 31% Gen 3 current todo
[_] 62% High priority
[_] Might be a good idea to use sparse arrays for things like marks...
| eliminate:
| - need for keeping things sorted all the time
| - speed-up access -- everything has the same index
| - speed-up modification -- just mirror all the operations
| - searching in more than one place
|
| introduce:
| - memory overhead - each array is always N elements
| - conversion on import, export and crop
| need to clear / insert all the nulls
|
| candidates:
| - marks
| - bookmarks
| - tags
[_] BUG: sorting breaks when at or near the end of a ribbon...
|
| Race condition...

View File

@ -35,6 +35,7 @@ function getAllData(){
//
// XXX should this set the .current to anything but null or the first elem???
function makeCroppedData(gids, keep_ribbons, keep_unloaded_gids){
gids = fastSortGIDsByOrder(gids)
var res = {
varsion: DATA_VERSION,
current: null,

View File

@ -23,6 +23,7 @@
// MARKED - marks data
// BOOKMARKS - bookmarks data
// BOOKMARKS_DATA - bookmarks metadata
// TAGS - tag data
//
//
// Changes:
@ -574,6 +575,36 @@ function binSearch(target, lst, check, return_position, get){
}
// Make a sparse gid list...
//
// NOTE: the resulting list will always be sorted...
// NOTE: this will skip all elements not in order
function makeSparceGIDList(gids, data){
data = data == null ? DATA : data
var order = data.order
var res = []
gids.forEach(function(e){
var i = order.indexOf(e)
if(i < 0){
return
}
res[i] = e
})
return res
}
// Remove all the undefined's form a sparse list...
//
function compactSparceList(lst){
return lst.filter(function(e){
return e !== undefined
})
}
// This is a cheating fast sort...
//
// By cheating we might use more memory -- this is both not in-place
@ -605,20 +636,7 @@ function binSearch(target, lst, check, return_position, get){
// On the down side, this has some memory overhead -- ~ N - n * ref
//
function fastSortGIDsByOrder(gids, data){
data = data == null ? DATA : data
var order = data.order
var res = []
// insert the gids to their order positions...
gids.forEach(function(gid){
res[order.indexOf(gid)] = gid
})
// clear out the nulls...
return res.filter(function(e){
return e != null
})
return compactSparceList(makeSparceGIDList(gids, data))
}
@ -794,7 +812,7 @@ function getAllGids(data){
// NOTE: this will return an unsorted list of gids...
// NOTE: this will sort the result unless either no_sort is true or gids
// is not given...
function getLoadedGIDs(gids, data, no_sort){
function getLoadedGIDs(gids, data){
data = data == null ? DATA : data
var res = []
data.ribbons.forEach(function(r){
@ -802,12 +820,9 @@ function getLoadedGIDs(gids, data, no_sort){
})
if(gids != null){
return gids.filter(function(e){
return res.indexOf(e) >= 0
return e == null ? false : (res.indexOf(e) >= 0)
})
}
if(!no_sort){
res = fastSortGIDsByOrder(res)
}
return res
}
@ -857,6 +872,8 @@ function insertGIDToPosition(gid, list, data){
//
// NOTE: if gid is present in the searched ribbon this will return it.
// NOTE: this uses it's own predicate...
//
// XXX make this undefined tolerant -- sparse list compatibility...
function getGIDBefore(gid, ribbon, data, search){
gid = gid == null ? getImageGID() : gid
data = data == null ? DATA : data
@ -2360,7 +2377,6 @@ function showImage(gid){
// NOTE: if no_reload_viewer is true, then no re-rendering is triggered.
function updateRibbonOrder(no_reload_viewer){
for(var i=0; i < DATA.ribbons.length; i++){
//DATA.ribbons[i].sort(imageOrderCmp)
DATA.ribbons[i] = fastSortGIDsByOrder(DATA.ribbons[i])
}
if(!no_reload_viewer){

View File

@ -101,6 +101,8 @@ function makeMarkedLister(get_marked){
// - number - ribbon index
// - list - list of gids used as source
// - null - same as all
//
// XXX with sparce lists this is trivial: get all the null indexes...
function makeUnmarkedLister(get_marked, get_cache){
return function(mode){
var marked = get_marked()
@ -138,9 +140,10 @@ var getUnmarked = makeUnmarkedLister(
function(){ return _UNMARKED_CACHE })
// XXX make this undefined tolerant -- sparse list compatibility...
var getMarkedGIDBefore = makeGIDBeforeGetterFromList(
function(){
return MARKED
return compactSparceList(MARKED)
})
@ -347,12 +350,12 @@ var toggleMark = makeMarkToggler(
// add marked image to list...
if(action == 'on'){
if(MARKED.indexOf(gid) == -1){
insertGIDToPosition(gid, MARKED)
MARKED[DATA.order.indexOf(gid)] = gid
}
// remove marked image from list...
} else {
MARKED.splice(MARKED.indexOf(gid), 1)
delete MARKED[MARKED.indexOf(gid)]
}
marksUpdated()
@ -360,7 +363,7 @@ var toggleMark = makeMarkToggler(
function toggleAllMarks(action, mode){
function setAllMarks(action, mode){
action = action == null ? toggleMark('?') : action
mode = mode == null ? 'ribbon' : mode
@ -369,8 +372,7 @@ function toggleAllMarks(action, mode){
if(action == 'on'){
var _update = function(e){
if(MARKED.indexOf(e) < 0){
//insertGIDToPosition(e, MARKED)
MARKED.push(e)
MARKED[DATA.order.indexOf(e)] = e
updated.push(e)
}
}
@ -378,7 +380,7 @@ function toggleAllMarks(action, mode){
var _update = function(e){
var i = MARKED.indexOf(e)
if(i >= 0){
MARKED.splice(i, 1)
delete MARKED[i]
updated.push(e)
}
}
@ -395,8 +397,6 @@ function toggleAllMarks(action, mode){
res.forEach(_update)
MARKED = fastSortGIDsByOrder(MARKED)
updateImages(updated)
$('.viewer').trigger('togglingMarks', [updated, action])
@ -411,7 +411,7 @@ function toggleAllMarks(action, mode){
// - 'all'
function removeImageMarks(mode){
mode = mode == null ? 'ribbon' : mode
var res = toggleAllMarks('off', mode)
var res = setAllMarks('off', mode)
$('.viewer').trigger('removingMarks', [res, mode])
return res
}
@ -419,7 +419,7 @@ function removeImageMarks(mode){
function markAll(mode){
mode = mode == null ? 'ribbon' : mode
var res = toggleAllMarks('on', mode)
var res = setAllMarks('on', mode)
$('.viewer').trigger('addingMarks', [res, mode])
return res
}
@ -435,14 +435,12 @@ function invertImageMarks(){
var i = MARKED.indexOf(e)
if(i == -1){
on.push(e)
MARKED.push(e)
//insertGIDToPosition(e, MARKED)
MARKED[DATA.order.indexOf(e)] = e
} else {
off.push(e)
MARKED.splice(i, 1)
delete MARKED[i]
}
})
MARKED = fastSortGIDsByOrder(MARKED)
updateImages(ribbon)
$('.viewer')
@ -477,10 +475,9 @@ function toggleMarkBlock(image){
}
// do the toggle...
if(state){
//insertGIDToPosition(e, MARKED)
MARKED.push(e)
MARKED[DATA.order.indexOf(e)] = e
} else {
MARKED.splice(MARKED.indexOf(e), 1)
delete MARKED[MARKED.indexOf(e)]
}
updated.push(e)
}
@ -494,8 +491,6 @@ function toggleMarkBlock(image){
var right = ribbon.slice(i+1)
$.each(right, _convert)
MARKED = fastSortGIDsByOrder(MARKED)
updateImages(updated)
$('.viewer')
@ -593,10 +588,10 @@ function shiftMarkedImagesRight(){
// of makeNextFromListAction(..) for more info)
var nextMark = makeNextFromListAction(
getMarkedGIDBefore,
function(){ return MARKED })
function(){ return compactSparceList(MARKED) })
var prevMark = makePrevFromListAction(
getMarkedGIDBefore,
function(){ return MARKED })
function(){ return compactSparceList(MARKED) })
var nextUnmarked = makeNextFromListAction(
@ -697,23 +692,7 @@ var loadFileMarks = makeFileLoader(
MARKED_FILE_PATTERN,
[],
function(data){
// set the MARKED...
MARKED = data
// for version below 2.1, sort MARKED and update to 2.1...
if(DATA.version == '2.0'){
setTimeout(function(){
var t0 = Date.now()
MARKED = fastSortGIDsByOrder(MARKED)
var t1 = Date.now()
marksUpdated()
DATA.version = DATA_VERSION
dataUpdated()
console.warn('Marks: sort: done ('+( t1 - t0 )+'ms) -- re-save the data.')
}, 0)
}
MARKED = makeSparceGIDList(data)
},
'marksLoaded')
@ -723,7 +702,7 @@ var saveFileMarks = makeFileSaver(
'Marks',
MARKED_FILE_DEFAULT,
function(){
return MARKED
return compactSparceList(MARKED)
})
@ -768,11 +747,20 @@ function setupMarks(viewer){
})
})
.on('sortedImages', function(){
MARKED = fastSortGIDsByOrder(MARKED)
MARKED = makeSparceGIDList(MARKED)
marksUpdated()
})
.on('horizontalShiftedImage', function(evt, gid, direction){
if(shiftGIDToOrderInList(gid, direction, MARKED)){
var n = DATA.order.indexOf(gid)
var o = MARKED.indexOf(gid)
// move the marked gid...
MARKED.splice(o, 1)
MARKED.splice(n, 0, gid)
// test if there are any marked images between n and o...
var shift = compactSparceList(MARKED.slice(Math.min(n, o)+1, Math.max(n, o)))
if(shift.length > 0){
marksUpdated()
}
})