sorting optimization 3
This commit is contained in:
@@ -422,6 +422,7 @@ def run_generation_loop(
|
||||
pending_batch = []
|
||||
current_job = 0
|
||||
total_generated = 0
|
||||
gen_index_offset = len(existing_data.get("items", [])) # Sequential index for deterministic sort ordering
|
||||
skipped_count = 0
|
||||
job_durations = []
|
||||
eta_start_time = time.time()
|
||||
@@ -1020,7 +1021,8 @@ def run_generation_loop(
|
||||
|
||||
meta = create_image_metadata(
|
||||
conf, w, h, duration, current_seed, batch_idx,
|
||||
actual_positive_prompt, actual_negative_prompt
|
||||
actual_positive_prompt, actual_negative_prompt,
|
||||
gen_index=gen_index_offset + total_generated
|
||||
)
|
||||
if pos_hash or neg_hash:
|
||||
meta["conditioning_pos_hash"] = pos_hash
|
||||
|
||||
+9
-5
@@ -141,10 +141,10 @@ def save_image_to_disk(image, output_dir, filename):
|
||||
return filepath
|
||||
|
||||
|
||||
def create_image_metadata(config, width, height, duration, seed, batch_idx, actual_positive_prompt, actual_negative_prompt):
|
||||
def create_image_metadata(config, width, height, duration, seed, batch_idx, actual_positive_prompt, actual_negative_prompt, gen_index=None):
|
||||
"""
|
||||
Create metadata dictionary for an image.
|
||||
|
||||
|
||||
Args:
|
||||
config: Configuration dictionary
|
||||
width: Image width
|
||||
@@ -154,7 +154,8 @@ def create_image_metadata(config, width, height, duration, seed, batch_idx, actu
|
||||
batch_idx: Batch index
|
||||
actual_positive_prompt: Final positive prompt (with triggers)
|
||||
actual_negative_prompt: Final negative prompt
|
||||
|
||||
gen_index: Sequential generation index for deterministic sort ordering (optional, backwards-compatible)
|
||||
|
||||
Returns:
|
||||
dict: Metadata dictionary
|
||||
"""
|
||||
@@ -178,7 +179,7 @@ def create_image_metadata(config, width, height, duration, seed, batch_idx, actu
|
||||
if meta.get("attention_mode") == "default":
|
||||
meta.pop("attention_mode", None)
|
||||
|
||||
meta.update({
|
||||
update_dict = {
|
||||
"width": width,
|
||||
"height": height,
|
||||
"duration": duration,
|
||||
@@ -186,7 +187,10 @@ def create_image_metadata(config, width, height, duration, seed, batch_idx, actu
|
||||
"batch_idx": batch_idx,
|
||||
"positive": actual_positive_prompt,
|
||||
"negative": actual_negative_prompt
|
||||
})
|
||||
}
|
||||
if gen_index is not None:
|
||||
update_dict["gen_index"] = gen_index
|
||||
meta.update(update_dict)
|
||||
|
||||
return meta
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const ASYNC_PIPELINE_THRESHOLD = 500;
|
||||
// current sort/filter, used for "Go To Card #" and the #N tag on cards.
|
||||
function refreshIndices() {
|
||||
if (!activeData) return;
|
||||
const sorted = activeData.slice().sort((a, b) => a.id - b.id);
|
||||
const sorted = activeData.slice().sort((a, b) => (a.gen_index ?? a.id) - (b.gen_index ?? b.id));
|
||||
idToIndexMap = new Map(sorted.map((item, index) => [item.id, index + 1]));
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ function setSecondarySort(id) {
|
||||
// Unified Comparison Helper
|
||||
function compareItems(a, b, sortKey) {
|
||||
switch (sortKey) {
|
||||
case 'newest': return b.id - a.id;
|
||||
case 'oldest': return a.id - b.id;
|
||||
case 'newest': return (b.gen_index ?? b.id) - (a.gen_index ?? a.id);
|
||||
case 'oldest': return (a.gen_index ?? a.id) - (b.gen_index ?? b.id);
|
||||
case 'fastest': return a.duration - b.duration;
|
||||
case 'favorited': return (b.favorited ? 1 : 0) - (a.favorited ? 1 : 0);
|
||||
case 'cfg': return a.cfg - b.cfg;
|
||||
@@ -199,9 +199,9 @@ function runMultiSort(list) {
|
||||
res = compareItems(a, b, currentSecondarySort);
|
||||
}
|
||||
|
||||
// 3. Fallback to ID (Stable sort)
|
||||
// 3. Fallback to gen_index/ID (Stable sort, backwards-compatible)
|
||||
if (res === 0) {
|
||||
return a.id - b.id;
|
||||
return (a.gen_index ?? a.id) - (b.gen_index ?? b.id);
|
||||
}
|
||||
return res;
|
||||
});
|
||||
@@ -313,10 +313,11 @@ function executePipeline() {
|
||||
});
|
||||
|
||||
// Apply sorting
|
||||
// Fast path: for oldest/newest with no secondary sort, items from activeData.filter()
|
||||
// are already in ID order — just reverse for newest
|
||||
// Fast path: for oldest/newest with no secondary sort, activeData is stored newest-first
|
||||
// (items are inserted/unshifted at position 0), so processedData after filter() is also newest-first.
|
||||
// For 'oldest' we reverse; for 'newest' it's already correct.
|
||||
if ((currentSort === 'oldest' || currentSort === 'newest') && currentSecondarySort === 'none') {
|
||||
if (currentSort === 'newest') {
|
||||
if (currentSort === 'oldest') {
|
||||
processedData.reverse();
|
||||
}
|
||||
} else {
|
||||
@@ -402,7 +403,7 @@ function binaryInsert(arr, item) {
|
||||
cmp = compareItems(arr[mid], item, currentSecondarySort);
|
||||
}
|
||||
if (cmp === 0) {
|
||||
cmp = arr[mid].id - item.id; // Stable sort fallback
|
||||
cmp = (arr[mid].gen_index ?? arr[mid].id) - (item.gen_index ?? item.id); // Stable sort fallback
|
||||
}
|
||||
if (cmp <= 0) {
|
||||
low = mid + 1;
|
||||
|
||||
@@ -242,7 +242,7 @@ function renderVisibleItems(forcePositionUpdate = false) {
|
||||
|
||||
itemsToShow.forEach((data, offsetIndex) => {
|
||||
const globalIndex = visibleRange.start + offsetIndex;
|
||||
const displayNumber = globalIndex + 1; // 1-based position in current sorted view
|
||||
const genOrderNumber = idToIndexMap.get(data.id) || (globalIndex + 1); // Generation order number (backwards-compatible)
|
||||
|
||||
const row = Math.floor(globalIndex / columnsCount);
|
||||
const col = globalIndex % columnsCount;
|
||||
@@ -259,9 +259,9 @@ function renderVisibleItems(forcePositionUpdate = false) {
|
||||
card.style.width = `${itemWidth - 10}px`;
|
||||
card.style.zIndex = globalIndex;
|
||||
|
||||
// Update card number to reflect sorted position
|
||||
// Update card number to reflect generation order
|
||||
const indexTag = card.querySelector('.index-tag');
|
||||
if (indexTag) indexTag.textContent = `#${displayNumber}`;
|
||||
if (indexTag) indexTag.textContent = `#${genOrderNumber}`;
|
||||
|
||||
nodeMap.set(data.id, card);
|
||||
fragment.appendChild(card);
|
||||
@@ -286,7 +286,7 @@ function renderVisibleItems(forcePositionUpdate = false) {
|
||||
|
||||
// Update card number when position changes (sort/filter changed)
|
||||
const indexTag = card.querySelector('.index-tag');
|
||||
if (indexTag) indexTag.textContent = `#${displayNumber}`;
|
||||
if (indexTag) indexTag.textContent = `#${genOrderNumber}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user