@@ -10,12 +10,14 @@ defmodule Cardian.CardRegistry do
1010 end
1111
1212 def get_card_by_id ( id ) do
13- GenServer . call ( :card_registry , { :get_card_by_id , id } )
13+ :cards
14+ |> :ets . lookup ( id )
1415 |> Enum . map ( & elem ( & 1 , 1 ) )
1516 end
1617
1718 def get_set_by_id ( id ) do
18- GenServer . call ( :card_registry , { :get_set_by_id , id } )
19+ :sets
20+ |> :ets . lookup ( id )
1921 |> Enum . map ( & elem ( & 1 , 1 ) )
2022 end
2123
@@ -27,16 +29,27 @@ defmodule Cardian.CardRegistry do
2729 end
2830
2931 def get_cards ( ) do
30- GenServer . call ( :card_registry , :get_cards )
32+ :cards
33+ |> :ets . tab2list ( )
34+ |> Enum . map ( & elem ( & 1 , 1 ) )
3135 end
3236
3337 def search_card ( query ) when is_binary ( query ) do
34- q = normalize_string ( query )
38+ query
39+ |> normalize_string ( )
40+ |> then ( & [ & 1 | tokenize_string ( & 1 ) ] )
41+ |> Stream . flat_map ( & :ets . lookup ( :index , & 1 ) )
42+ |> Stream . flat_map ( & elem ( & 1 , 1 ) )
43+ |> Enum . frequencies ( )
44+ |> Enum . sort_by ( & elem ( & 1 , 1 ) , :desc )
45+ |> Enum . flat_map ( & get_card_by_id ( elem ( & 1 , 0 ) ) )
46+ end
3547
36- get_cards ( )
37- |> Stream . filter ( & String . contains? ( normalize_string ( elem ( & 1 , 1 ) . name ) , q ) )
38- |> Stream . map ( & elem ( & 1 , 1 ) )
39- |> Enum . to_list ( )
48+ defp tokenize_string ( string ) when is_binary ( string ) do
49+ string
50+ |> String . graphemes ( )
51+ |> Stream . chunk_every ( 3 , 1 , :discard )
52+ |> Enum . map ( & Enum . join ( & 1 ) )
4053 end
4154
4255 defp normalize_string ( string ) when is_binary ( string ) do
@@ -50,48 +63,36 @@ defmodule Cardian.CardRegistry do
5063 @ impl true
5164 def init ( _ ) do
5265 Logger . info ( "Starting Card Registry" )
53- cards = :ets . new ( :cards , [ :set , :protected , :named_table , read_concurrency: true ] )
54- sets = :ets . new ( :sets , [ :set , :protected , :named_table , read_concurrency: true ] )
66+ :cards = :ets . new ( :cards , [ :set , :protected , :named_table , read_concurrency: true ] )
67+ :sets = :ets . new ( :sets , [ :set , :protected , :named_table , read_concurrency: true ] )
68+ :index = :ets . new ( :index , [ :set , :protected , :named_table , read_concurrency: true ] )
5569
5670 Process . send ( self ( ) , :update_registry , [ ] )
57- { :ok , { cards , sets } }
71+ { :ok , nil }
5872 end
5973
6074 @ impl true
61- def handle_call ( { :get_card_by_id , id } , _from , { cards , sets } ) do
62- { :reply , :ets . lookup ( cards , id ) , { cards , sets } }
63- end
64-
65- @ impl true
66- def handle_call ( { :get_set_by_id , id } , _from , { cards , sets } ) do
67- { :reply , :ets . lookup ( sets , id ) , { cards , sets } }
68- end
75+ def handle_info ( :update_registry , _ ) do
76+ update_cards ( )
77+ update_sets ( )
78+ generate_index ( )
6979
70- @ impl true
71- def handle_call ( :get_cards , _from , { cards , sets } ) do
72- { :reply , :ets . tab2list ( cards ) , { cards , sets } }
73- end
74-
75- @ impl true
76- def handle_info ( :update_registry , { cards , sets } ) do
77- update_cards ( cards )
78- update_sets ( sets )
7980 schedule_update ( )
80- { :noreply , { cards , sets } }
81+ { :noreply , nil }
8182 rescue
8283 err ->
8384 Logger . error ( Exception . format ( :error , err , __STACKTRACE__ ) )
8485 Logger . error ( "Update failed. Rescheduling..." )
8586 schedule_update ( )
86- { :noreply , { cards , sets } }
87+ { :noreply , nil }
8788 end
8889
89- defp update_sets ( sets ) do
90+ defp update_sets ( ) do
9091 new_sets = Masterduelmeta . get_all_sets ( )
9192
9293 true =
9394 :ets . insert (
94- sets ,
95+ : sets,
9596 [
9697 { "61fc6622c491eb1813d4c85c" ,
9798 % Cardian.Model.Set {
@@ -110,12 +111,32 @@ defmodule Cardian.CardRegistry do
110111 Logger . info ( "Sets updated" )
111112 end
112113
113- defp update_cards ( cards ) do
114+ defp update_cards ( ) do
114115 new_cards = Masterduelmeta . get_all_cards ( )
115- true = :ets . insert ( cards , Enum . map ( new_cards , & { & 1 . id , & 1 } ) )
116+ # true = :ets.insert(:cards, Enum.map(new_cards, &{&1.id, &1, tokenize_string(&1.name)}))
117+ true = :ets . insert ( :cards , Enum . map ( new_cards , & { & 1 . id , & 1 } ) )
116118 Logger . info ( "Cards updated" )
117119 end
118120
121+ defp generate_index ( ) do
122+ index =
123+ get_cards ( )
124+ |> Stream . flat_map ( fn card ->
125+ card . name
126+ |> normalize_string ( )
127+ |> then ( & [ & 1 | tokenize_string ( & 1 ) ] )
128+ |> Stream . map ( & % { token: & 1 , id: card . id } )
129+ end )
130+ |> Enum . reduce ( % { } , fn elem , acc ->
131+ Map . update ( acc , elem . token , MapSet . new ( [ elem . id ] ) , & MapSet . put ( & 1 , elem . id ) )
132+ end )
133+ |> Map . to_list ( )
134+
135+ true = :ets . insert ( :index , index )
136+
137+ Logger . info ( "Index generated" )
138+ end
139+
119140 defp schedule_update ( ) do
120141 Process . send_after (
121142 :card_registry ,
0 commit comments