Looking into this further myself, I found that the problem is fairly easily
reproducible even without my specific database.

I have attached a set of 1,000 generated sample images, containing 2,111
tags among them, with no more than 10 per file. To reproduce the problem,
import these images into a freshly created Darktable database, select the
"tag" option in the "collect images" panel, and watch Darktable spin its
wheels.

I have also attached the Python script used to generate the sample images.

--
August Schwerdfeger
[email protected]


On Tue, Mar 15, 2016 at 11:54 PM, August Schwerdfeger <
[email protected]> wrote:

> I tried starting up Darktable using a fresh configuration directory and
> new database file and rebuilding the problematic database from XMP sidecar
> files. This did not fix the problem.
>
> --
> August Schwerdfeger
> [email protected]
>
> On Tue, Mar 15, 2016 at 3:56 PM, KOVÁCS István <[email protected]>
> wrote:
>
>> A missing index?
>>
>
>

____________________________________________________________________________
darktable user mailing list
to unsubscribe send a mail to [email protected]

#!/usr/bin/python

# (C) 2016 August Schwerdfeger

# This script:
#   1. creates a directory (by default 'TestImages' in the current working
#      directory);
#   2. populates it with a given number of image files (by default 1000)
#      with names of the form 'DSC_abcd.png', where 'abcd' is a decimal
#      number between 0 and 9999;
#   3. uses the exiv2 library to tag each image with a set of several
#      hierarchical tags ('Filename|Contains|X' for each distinct substring
#      X of 'abcd') and the corresponding set of non-hierarchical tags.
#
# The image copied to generate these image files is by default a 1x1 PNG
# image with a black pixel, but this can be changed with the '--baseImage'
# command-line option.
#
# The script requires version 0.25 of the exiv2 library due to an issue
# with the assumed type of the 'Xmp.lr.hierarchicalSubject' tag (see
# http://dev.exiv2.org/issues/784 for details).
#
# If the set of images thus generated is imported into a new Darktable
# database, Darktable will become very sluggish and use large amounts
# of CPU and memory at any interaction involving the "tag" option in
# the "collect images" panel.

import argparse
import os.path
import shutil
import sys

import gi
gi.require_version("GExiv2","0.10")
from gi.repository import GExiv2

# This is a 1x1 PNG image with a black pixel.
DEFAULT_BASE_IMAGE = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53\xde\x00\x00\x00\x0c\x49\x44\x41\x54\x08\xd7\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01\x27\x34\x27\x0a\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"

def generateTestImages(baseImage,toDir,n):
    ext = os.path.splitext(baseImage)[1] if baseImage else ".png"
    for i in range(n):
        strI = "%04d" % i
        if baseImage:
            filenameI = os.path.join(toDir,"DSC_%s%s" % (strI,ext))
            shutil.copy(baseImage,filenameI)
        else:
            with open(os.path.join(toDir,"DSC_%s.png" % strI),"w") as fp:
                fp.write(DEFAULT_BASE_IMAGE)

def generateTags(baseImage,toDir,n):
    ext = os.path.splitext(baseImage)[1] if baseImage else ".png"
    for i in range(n):
        strI = "%04d" % i
        filenameI = os.path.join(toDir,"DSC_%s%s" % (strI,ext))
        metadata = GExiv2.Metadata(filenameI)
        metadata.register_xmp_namespace("http://purl.org/dc/elements/1.1/","dc";)
        metadata.register_xmp_namespace("http://ns.adobe.com/lightroom/1.0/","lr";)
        hierarchicalTags = set([])
        tags = set(["Filename","Contains"])
        for j in range(len(strI)):
            for k in range(j+1,len(strI)+1):
                hierarchicalTags.add("Filename|Contains|%s" % strI[j:k])
                tags.add(strI[j:k])
        metadata.set_tag_multiple("Xmp.dc.subject",sorted(list(tags)))
        metadata.set_tag_multiple("Xmp.lr.hierarchicalSubject",sorted(list(hierarchicalTags)))
        metadata.save_file()

def main(args):
    baseImage = args.baseImage
    toDir = args.toDir
    imageCount = args.size

    if baseImage and not os.path.exists(baseImage):
        print >> sys.stderr,"Base image %s does not exist" % baseImage
        return 1
    if os.path.exists(toDir):
        print >> sys.stderr,"Images directory %s already exists" % toDir
        return 1
    if imageCount > 10000:
        print >> sys.stderr,"The generation of more than 10,000 images is not supported"
        return 1

    os.makedirs(toDir)
    generateTestImages(baseImage,toDir,imageCount)
    generateTags(baseImage,toDir,imageCount)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Generate sets of images illustrating undesirable behavior in Darktable")
    parser.add_argument("--toDir",type=str,metavar="DESTINATION_DIR",default="TestImages",help="The directory in which the test images will be placed. Must not exist at the time the script is run.")
    parser.add_argument("--baseImage",type=str,metavar="BASE_IMAGE",default=None,help="The image to use as the basis for the test images; defaults to a 1x1 PNG image with a black pixel.")
    parser.add_argument("--size",type=int,metavar="NUMBER_OF_IMAGES",default=1000,help="The number of images to generate; default 1000")
    args = parser.parse_args()
    errorlevel = main(args)
    sys.exit(errorlevel)

Attachment: TestImages-1000.tar.gz
Description: GNU Zip compressed data

Reply via email to