-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add filter search and related packages
Add filter search feature to search documents by filter. The 'biomap' package, which provides a bidirectional map, is also added to support this feature. The filter function filters only the lines containing word in the current document and creates a new document. Link the line numbers of the new document to the line numbers of the original document.
- Loading branch information
Showing
17 changed files
with
354 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package biomap | ||
|
||
import "sync" | ||
|
||
type Map[k comparable, v comparable] struct { | ||
s sync.RWMutex | ||
Forward map[k]v | ||
Backward map[v]k | ||
} | ||
|
||
func NewMap[k comparable, v comparable]() *Map[k, v] { | ||
return &Map[k, v]{ | ||
Forward: make(map[k]v), | ||
Backward: make(map[v]k), | ||
} | ||
} | ||
|
||
func (m *Map[k, v]) Store(key k, value v) { | ||
m.s.Lock() | ||
defer m.s.Unlock() | ||
m.Forward[key] = value | ||
m.Backward[value] = key | ||
} | ||
|
||
func (m *Map[k, v]) LoadForward(key k) (value v, ok bool) { | ||
m.s.RLock() | ||
defer m.s.RUnlock() | ||
value, ok = m.Forward[key] | ||
return | ||
} | ||
|
||
func (m *Map[k, v]) LoadBackward(value v) (key k, ok bool) { | ||
m.s.RLock() | ||
defer m.s.RUnlock() | ||
key, ok = m.Backward[value] | ||
return | ||
} | ||
|
||
func (m *Map[k, v]) DeleteForward(key k) { | ||
m.s.Lock() | ||
defer m.s.Unlock() | ||
value, ok := m.Forward[key] | ||
if !ok { | ||
return | ||
} | ||
delete(m.Forward, key) | ||
delete(m.Backward, value) | ||
} | ||
|
||
func (m *Map[k, v]) DeleteBackward(value v) { | ||
m.s.Lock() | ||
defer m.s.Unlock() | ||
key, ok := m.Backward[value] | ||
if !ok { | ||
return | ||
} | ||
delete(m.Forward, key) | ||
delete(m.Backward, value) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package biomap | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestMap(t *testing.T) { | ||
m := NewMap[int, string]() | ||
|
||
// Test Store and LoadForward | ||
m.Store(1, "one") | ||
value, ok := m.LoadForward(1) | ||
if !ok || value != "one" { | ||
t.Errorf("LoadForward failed. Expected value: %s, got: %s", "one", value) | ||
} | ||
|
||
// Test LoadBackward | ||
key, ok := m.LoadBackward("one") | ||
if !ok || key != 1 { | ||
t.Errorf("LoadBackward failed. Expected key: %d, got: %d", 1, key) | ||
} | ||
|
||
// Test DeleteForward | ||
m.DeleteForward(1) | ||
_, ok = m.LoadForward(1) | ||
if ok { | ||
t.Errorf("DeleteForward failed. Key still exists in Forward map") | ||
} | ||
|
||
// Test DeleteBackward | ||
m.DeleteBackward("one") | ||
_, ok = m.LoadBackward("one") | ||
if ok { | ||
t.Errorf("DeleteBackward failed. Value still exists in Backward map") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package oviewer | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"io" | ||
"log" | ||
"strings" | ||
) | ||
|
||
func (root *Root) filter(ctx context.Context) { | ||
searcher := root.setSearcher(root.input.value, root.Config.CaseSensitive) | ||
if searcher == nil { | ||
if root.Doc.jumpTargetSection { | ||
root.Doc.jumpTargetNum = 0 | ||
} | ||
return | ||
} | ||
word := root.searcher.String() | ||
root.setMessagef("filter:%v (%v)Cancel", word, strings.Join(root.cancelKeys, ",")) | ||
|
||
m := root.Doc | ||
r, w := io.Pipe() | ||
filterDoc, err := renderDoc(m, r) | ||
if err != nil { | ||
log.Println(err) | ||
return | ||
} | ||
filterDoc.FileName = fmt.Sprintf("filter:%s:%v", m.FileName, word) | ||
filterDoc.Caption = fmt.Sprintf("%s:%v", m.FileName, word) | ||
root.addDocument(filterDoc.Document) | ||
|
||
if m.Header > 0 { | ||
for ln := m.SkipLines; ln < m.Header; ln++ { | ||
line, err := m.Line(ln) | ||
if err != nil { | ||
break | ||
} | ||
filterDoc.lineNumMap.Store(ln, ln) | ||
w.Write(line) | ||
w.Write([]byte("\n")) | ||
} | ||
} | ||
|
||
filterDoc.writer = w | ||
filterDoc.Header = m.Header | ||
filterDoc.SkipLines = m.SkipLines | ||
|
||
go m.searchWriter(ctx, searcher, filterDoc, m.firstLine()) | ||
root.setMessagef("filter:%v", word) | ||
} | ||
|
||
// searchWriter searches the document and writes the result to w. | ||
func (m *Document) searchWriter(ctx context.Context, searcher Searcher, renderDoc *renderDocument, ln int) { | ||
defer renderDoc.writer.Close() | ||
nextLN := ln | ||
for { | ||
lineNum, err := m.searchLine(ctx, searcher, true, nextLN) | ||
if err != nil { | ||
break | ||
} | ||
line, err := m.Line(lineNum) | ||
if err != nil { | ||
break | ||
} | ||
num := lineNum | ||
if m.lineNumMap != nil { | ||
if n, ok := m.lineNumMap.LoadForward(num); ok { | ||
num = n | ||
} | ||
} | ||
renderDoc.lineNumMap.Store(ln, num) | ||
renderDoc.writer.Write(line) | ||
renderDoc.writer.Write([]byte("\n")) | ||
nextLN = lineNum + 1 | ||
ln++ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.