11package backend
22
33import (
4+ "fmt"
45 "sort"
56
67 "github.com/hyp3rd/hypercache/types"
78)
89
10+ // itemSorter is a custom sorter for the items
11+ type itemSorter struct {
12+ items []* types.Item
13+ less func (i , j * types.Item ) bool
14+ }
15+
16+ func (s * itemSorter ) Len () int { return len (s .items ) }
17+ func (s * itemSorter ) Swap (i , j int ) { s .items [i ], s .items [j ] = s .items [j ], s .items [i ] }
18+ func (s * itemSorter ) Less (i , j int ) bool { return s .less (s .items [i ], s .items [j ]) }
19+
920// IFilter is a backend agnostic interface for a filter that can be applied to a list of items.
1021type IFilter interface {
11- ApplyFilter (backendType string , items []* types.Item ) []* types.Item
22+ ApplyFilter (backendType string , items []* types.Item ) ( []* types.Item , error )
1223}
1324
1425// sortByFilter is a filter that sorts the items by a given field.
1526type sortByFilter struct {
1627 field string
1728}
1829
19- // ApplyFilter applies the sort filter to the given list of items.
20- func (f sortByFilter ) ApplyFilter (backendType string , items []* types.Item ) []* types.Item {
21- var sorter sort.Interface
22- switch f .field {
23- case types .SortByKey .String ():
24- sorter = & itemSorterByKey {items : items }
25- case types .SortByLastAccess .String ():
26- sorter = & itemSorterByLastAccess {items : items }
27- case types .SortByAccessCount .String ():
28- sorter = & itemSorterByAccessCount {items : items }
29- case types .SortByExpiration .String ():
30- sorter = & itemSorterByExpiration {items : items }
31- default :
32- return items
33- }
34- sort .Sort (sorter )
35- return items
36- }
37-
3830// SortOrderFilter is a filter that sorts the items by a given field.
3931type SortOrderFilter struct {
4032 ascending bool
4133}
4234
43- // ApplyFilter applies the sort order filter to the given list of items.
44- func (f SortOrderFilter ) ApplyFilter (backendType string , items []* types.Item ) []* types.Item {
45- if ! f .ascending {
46- sort .Slice (items , func (i , j int ) bool {
47- return items [j ].Key > items [i ].Key
48- })
49- } else {
50- sort .Slice (items , func (i , j int ) bool {
51- return items [i ].Key < items [j ].Key
52- })
53- }
54- return items
55- }
56-
5735// filterFunc is a filter that filters the items by a given field's value.
5836type filterFunc struct {
5937 fn func (item * types.Item ) bool
6038}
6139
62- // ApplyFilter applies the filter function to the given list of items.
63- func (f filterFunc ) ApplyFilter (backendType string , items []* types.Item ) []* types.Item {
64- filteredItems := make ([]* types.Item , 0 )
65- for _ , item := range items {
66- if f .fn (item ) {
67- filteredItems = append (filteredItems , item )
68- }
69- }
70- return filteredItems
71- }
72-
7340// WithSortBy returns a filter that sorts the items by a given field.
7441func WithSortBy (field string ) IFilter {
7542 return sortByFilter {field : field }
7643}
7744
78- // WithSortOrderAsc returns a filter that determins whether to sort ascending or not.
45+ // WithSortOrderAsc returns a filter that determines whether to sort ascending or not.
7946func WithSortOrderAsc (ascending bool ) SortOrderFilter {
8047 return SortOrderFilter {ascending : ascending }
8148}
@@ -84,3 +51,65 @@ func WithSortOrderAsc(ascending bool) SortOrderFilter {
8451func WithFilterFunc (fn func (item * types.Item ) bool ) IFilter {
8552 return filterFunc {fn : fn }
8653}
54+
55+ // ApplyFilter applies the sort by filter to the given list of items.
56+ func (f sortByFilter ) ApplyFilter (backendType string , items []* types.Item ) ([]* types.Item , error ) {
57+ var sorter * itemSorter
58+
59+ switch f .field {
60+ case types .SortByKey .String ():
61+ sorter = & itemSorter {
62+ items : items ,
63+ less : func (i , j * types.Item ) bool {
64+ return i .Key < j .Key
65+ },
66+ }
67+ case types .SortByLastAccess .String ():
68+ sorter = & itemSorter {
69+ items : items ,
70+ less : func (i , j * types.Item ) bool {
71+ return i .LastAccess .UnixNano () < j .LastAccess .UnixNano ()
72+ },
73+ }
74+ case types .SortByAccessCount .String ():
75+ sorter = & itemSorter {
76+ items : items ,
77+ less : func (i , j * types.Item ) bool {
78+ return i .AccessCount < j .AccessCount
79+ },
80+ }
81+ case types .SortByExpiration .String ():
82+ sorter = & itemSorter {
83+ items : items ,
84+ less : func (i , j * types.Item ) bool {
85+ return i .Expiration < j .Expiration
86+ },
87+ }
88+ default :
89+ return nil , fmt .Errorf ("invalid sort field: %s" , f .field )
90+ }
91+
92+ sort .Sort (sorter )
93+ return items , nil
94+ }
95+
96+ // ApplyFilter applies the sort order filter to the given list of items.
97+ func (f SortOrderFilter ) ApplyFilter (backendType string , items []* types.Item ) ([]* types.Item , error ) {
98+ if ! f .ascending {
99+ for i , j := 0 , len (items )- 1 ; i < j ; i , j = i + 1 , j - 1 {
100+ items [i ], items [j ] = items [j ], items [i ]
101+ }
102+ }
103+ return items , nil
104+ }
105+
106+ // ApplyFilter applies the filter function to the given list of items.
107+ func (f filterFunc ) ApplyFilter (backendType string , items []* types.Item ) ([]* types.Item , error ) {
108+ filteredItems := make ([]* types.Item , 0 )
109+ for _ , item := range items {
110+ if f .fn (item ) {
111+ filteredItems = append (filteredItems , item )
112+ }
113+ }
114+ return filteredItems , nil
115+ }
0 commit comments