diff --git a/BasicMap.go b/BasicMap.go index bbc460a..d270466 100644 --- a/BasicMap.go +++ b/BasicMap.go @@ -41,6 +41,32 @@ func (b *basicMapStorage) atleast(kind goimagehash.Kind, maxDistance int, search return matchingHashes } +func (b *basicMapStorage) exactMatches(hashes []Hash, max int) []Result { + var foundMatches []Result + for _, hash := range hashes { + mappedIds := map[*[]ID]bool{} + + index, count := b.findHash(hash) + if count > 0 { + for _, storedHash := range (*b.getCurrentHashes(hash.Kind))[index : index+count] { + ids := b.ids[storedHash.ID] + if mappedIds[ids] { + continue + } + mappedIds[ids] = true + + foundMatches = append(foundMatches, Result{ + Distance: 0, + Hash: storedHash.Hash, + IDs: ToIDList(*b.ids[storedHash.ID]), + }) + } + } + + } + return foundMatches +} + func (b *basicMapStorage) GetMatches(hashes []Hash, max int, exactOnly bool) ([]Result, error) { var ( foundMatches []Result @@ -52,31 +78,12 @@ func (b *basicMapStorage) GetMatches(hashes []Hash, max int, exactOnly bool) ([] defer b.hashMutex.RUnlock() if exactOnly { // exact matches are also found by partial matches. Don't bother with exact matches so we don't have to de-duplicate - for _, hash := range hashes { - mappedIds := map[*[]ID]bool{} - - index, count := b.findHash(hash) - if count > 0 { - for _, storedHash := range (*b.getCurrentHashes(hash.Kind))[index : index+count] { - ids := b.ids[storedHash.ID] - if mappedIds[ids] { - continue - } - mappedIds[ids] = true - - foundMatches = append(foundMatches, Result{ - Distance: 0, - Hash: storedHash.Hash, - IDs: ToIDList(*b.ids[storedHash.ID]), - }) - } - } - - } + foundMatches = b.exactMatches(hashes, max) tl.logTime("Search Exact") - - return foundMatches, nil + if len(foundMatches) > 0 { + return foundMatches, nil + } } foundHashes := make(map[uint64]struct{}) diff --git a/map.go b/map.go index 2969c4c..d3addd5 100644 --- a/map.go +++ b/map.go @@ -23,8 +23,13 @@ func (m *MapStorage) GetMatches(hashes []Hash, max int, exactOnly bool) ([]Resul m.hashMutex.RLock() defer m.hashMutex.RUnlock() - if exactOnly { - return m.basicMapStorage.GetMatches(hashes, max, exactOnly) + if exactOnly { // exact matches are also found by partial matches. Don't bother with exact matches so we don't have to de-duplicate + foundMatches = m.exactMatches(hashes, max) + + tl.logTime("Search Exact") + if len(foundMatches) > 0 { + return foundMatches, nil + } } tl.resetTime() defer tl.logTime("Search Complete") diff --git a/sqlite.go b/sqlite.go index fafdb47..07e8710 100644 --- a/sqlite.go +++ b/sqlite.go @@ -150,7 +150,10 @@ func (s *sqliteStorage) GetMatches(hashes []Hash, max int, exactOnly bool) ([]Re }) } - return foundMatches, nil + tl.logTime("Search Exact") + if len(foundMatches) > 0 { + return foundMatches, nil + } } foundHashes := make(map[uint64]struct{}) diff --git a/vp-tree.go b/vp-tree.go index 933483f..aba1fca 100644 --- a/vp-tree.go +++ b/vp-tree.go @@ -69,7 +69,7 @@ func (v *VPTree) GetMatches(hashes []Hash, max int, exactOnly bool) ([]Result, e } } } - if exactOnly { + if exactOnly && len(exactMatches) > 0 { return exactMatches, nil } exactMatches = append(exactMatches, matches...)