Indexer: Improve merging and performance
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
fd53d30caa
commit
4ac0ef3556
3 changed files with 28 additions and 22 deletions
|
@ -1,10 +1,14 @@
|
||||||
package entity
|
package entity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/photoprism/photoprism/pkg/rnd"
|
"github.com/photoprism/photoprism/pkg/rnd"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var photoMergeMutex = sync.Mutex{}
|
||||||
|
|
||||||
// ResolvePrimary ensures there is only one primary file for a photo.
|
// ResolvePrimary ensures there is only one primary file for a photo.
|
||||||
func (m *Photo) ResolvePrimary() error {
|
func (m *Photo) ResolvePrimary() error {
|
||||||
var file File
|
var file File
|
||||||
|
@ -29,7 +33,7 @@ func (m *Photo) Identical(includeMeta, includeUuid bool) (identical Photos, err
|
||||||
"OR (uuid = ? AND photo_stack > -1)"+
|
"OR (uuid = ? AND photo_stack > -1)"+
|
||||||
"OR (photo_path = ? AND photo_name = ?)",
|
"OR (photo_path = ? AND photo_name = ?)",
|
||||||
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.UUID, m.PhotoPath, m.PhotoName).
|
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.UUID, m.PhotoPath, m.PhotoName).
|
||||||
Order("id ASC").Find(&identical).Error; err != nil {
|
Order("photo_quality DESC, id ASC").Find(&identical).Error; err != nil {
|
||||||
return identical, err
|
return identical, err
|
||||||
}
|
}
|
||||||
case includeMeta && m.HasLocation() && m.HasLatLng() && m.TakenSrc == SrcMeta:
|
case includeMeta && m.HasLocation() && m.HasLatLng() && m.TakenSrc == SrcMeta:
|
||||||
|
@ -37,20 +41,20 @@ func (m *Photo) Identical(includeMeta, includeUuid bool) (identical Photos, err
|
||||||
Where("(taken_at = ? AND taken_src = 'meta' AND photo_stack > -1 AND cell_id = ? AND camera_serial = ? AND camera_id = ?) "+
|
Where("(taken_at = ? AND taken_src = 'meta' AND photo_stack > -1 AND cell_id = ? AND camera_serial = ? AND camera_id = ?) "+
|
||||||
"OR (photo_path = ? AND photo_name = ?)",
|
"OR (photo_path = ? AND photo_name = ?)",
|
||||||
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.PhotoPath, m.PhotoName).
|
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.PhotoPath, m.PhotoName).
|
||||||
Order("id ASC").Find(&identical).Error; err != nil {
|
Order("photo_quality DESC, id ASC").Find(&identical).Error; err != nil {
|
||||||
return identical, err
|
return identical, err
|
||||||
}
|
}
|
||||||
case includeUuid && rnd.IsUUID(m.UUID):
|
case includeUuid && rnd.IsUUID(m.UUID):
|
||||||
if err := Db().
|
if err := Db().
|
||||||
Where("(uuid = ? AND photo_stack > -1) OR (photo_path = ? AND photo_name = ?)",
|
Where("(uuid = ? AND photo_stack > -1) OR (photo_path = ? AND photo_name = ?)",
|
||||||
m.UUID, m.PhotoPath, m.PhotoName).
|
m.UUID, m.PhotoPath, m.PhotoName).
|
||||||
Order("id ASC").Find(&identical).Error; err != nil {
|
Order("photo_quality DESC, id ASC").Find(&identical).Error; err != nil {
|
||||||
return identical, err
|
return identical, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := Db().
|
if err := Db().
|
||||||
Where("photo_path = ? AND photo_name = ?", m.PhotoPath, m.PhotoName).
|
Where("photo_path = ? AND photo_name = ?", m.PhotoPath, m.PhotoName).
|
||||||
Order("id ASC").Find(&identical).Error; err != nil {
|
Order("photo_quality DESC, id ASC").Find(&identical).Error; err != nil {
|
||||||
return identical, err
|
return identical, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +64,9 @@ func (m *Photo) Identical(includeMeta, includeUuid bool) (identical Photos, err
|
||||||
|
|
||||||
// Merge photo with identical ones.
|
// Merge photo with identical ones.
|
||||||
func (m *Photo) Merge(mergeMeta, mergeUuid bool) (original Photo, merged Photos, err error) {
|
func (m *Photo) Merge(mergeMeta, mergeUuid bool) (original Photo, merged Photos, err error) {
|
||||||
|
photoMergeMutex.Lock()
|
||||||
|
defer photoMergeMutex.Unlock()
|
||||||
|
|
||||||
identical, err := m.Identical(mergeMeta, mergeUuid)
|
identical, err := m.Identical(mergeMeta, mergeUuid)
|
||||||
|
|
||||||
if len(identical) < 2 || err != nil {
|
if len(identical) < 2 || err != nil {
|
||||||
|
@ -110,11 +117,5 @@ func (m *Photo) Merge(mergeMeta, mergeUuid bool) (original Photo, merged Photos,
|
||||||
m.PhotoQuality = -1
|
m.PhotoQuality = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
original.PhotoQuality = original.QualityScore()
|
|
||||||
|
|
||||||
if err := original.Save(); err != nil {
|
|
||||||
log.Errorf("photo: %s in %s (merge)", err, original.PhotoName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return original, merged, err
|
return original, merged, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,3 +67,14 @@ func (m *Photo) QualityScore() (score int) {
|
||||||
|
|
||||||
return score
|
return score
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateQuality updates the photo quality attribute.
|
||||||
|
func (m *Photo) UpdateQuality() error {
|
||||||
|
if m.DeletedAt != nil || m.PhotoQuality < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m.PhotoQuality = m.QualityScore()
|
||||||
|
|
||||||
|
return m.Update("PhotoQuality", m.PhotoQuality)
|
||||||
|
}
|
||||||
|
|
|
@ -749,7 +749,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||||
photo.PhotoQuality = photo.QualityScore()
|
photo.PhotoQuality = photo.QualityScore()
|
||||||
|
|
||||||
if err := photo.Save(); err != nil {
|
if err := photo.Save(); err != nil {
|
||||||
log.Errorf("index: %s in %s (update photo metadata)", err, logName)
|
log.Errorf("index: %s in %s (update metadata)", err, logName)
|
||||||
result.Status = IndexFailed
|
result.Status = IndexFailed
|
||||||
result.Err = err
|
result.Err = err
|
||||||
return result
|
return result
|
||||||
|
@ -762,17 +762,11 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||||
if err := photo.IndexKeywords(); err != nil {
|
if err := photo.IndexKeywords(); err != nil {
|
||||||
log.Errorf("index: %s in %s (save keywords)", err, logName)
|
log.Errorf("index: %s in %s (save keywords)", err, logName)
|
||||||
}
|
}
|
||||||
} else if photo.DeletedAt == nil {
|
} else if err := photo.UpdateQuality(); err != nil {
|
||||||
if photo.PhotoQuality >= 0 {
|
log.Errorf("index: %s in %s (update quality)", err, logName)
|
||||||
photo.PhotoQuality = photo.QualityScore()
|
result.Status = IndexFailed
|
||||||
}
|
result.Err = err
|
||||||
|
return result
|
||||||
if err := photo.Save(); err != nil {
|
|
||||||
log.Errorf("index: %s in %s (update photo quality)", err, logName)
|
|
||||||
result.Status = IndexFailed
|
|
||||||
result.Err = err
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Status = IndexUpdated
|
result.Status = IndexUpdated
|
||||||
|
|
Loading…
Reference in a new issue