Skip to content

Commit 2f4fcfd

Browse files
committed
README
1 parent 7675048 commit 2f4fcfd

File tree

1 file changed

+238
-0
lines changed

1 file changed

+238
-0
lines changed

README.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Least Recently Used
2+
Potent implementation of LRU algorithm based on counters with support of common counter up to once quadrillion hits.
3+
4+
5+
Reference Guide
6+
===============
7+
8+
## description
9+
This is implementation of LRU algorithm based on counters with support of common counter up to once quadrillion hits.
10+
11+
#### tasks:
12+
13+
* Algorithm accumulates any actions by keys in outside system.
14+
* Algorithm executes fetching keys for follow deletion from outside system.
15+
16+
#### more:
17+
18+
* https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
19+
20+
#### notes:
21+
##### note №1:
22+
Note that the implementation of algorithm support two interaction modes:
23+
24+
###### internal
25+
26+
like OTP application into your Erlang node
27+
28+
###### external
29+
30+
like daemon into your Unix-like OS
31+
32+
But actually nothing forbidens to interact in both modes at same time.
33+
34+
35+
##### note №2:
36+
Note that the implementation of algorithm stores keys in binary, that is, for set of keys from the first example bellow key will be stored as in second example:
37+
38+
###### example №1
39+
40+
<<"moscow">>
41+
["moscow"]
42+
"moscow"
43+
moscow
44+
45+
###### example №2
46+
47+
<<"moscow">>
48+
49+
50+
## launch options
51+
52+
[{lru,[
53+
{ets_dir,"priv"}, %% !!! must be string type !!!!!
54+
{ets_sync_reset,true}, %% !!! must be atom type !!!!!
55+
{ets_recovery,true}, %% !!! must be atom type !!!!!
56+
{tcp,on}, %% !!! must be atom type !!!!!
57+
{mode,inet}, %% !!! must be atom type !!!!!
58+
{port,7777}, %% !!! must be atom type !!!!!
59+
{ip,{127,0,0,1}}, %% !!! must be tuple type !!!!!
60+
{unix,"/var/run/lru/unix"}, %% !!! must by string type !!!!!
61+
{num_acceptors,100}, %% !!! must by integer type !!!!!
62+
{max_connections,1024}, %% !!! must by integer type !!!!!
63+
{max_key_size,72} %% !!! must be integer type !!!!!
64+
]}].
65+
66+
#### ets_dir
67+
path to directory storage ets-tables, relative to the root directory of application
68+
69+
#### ets_sync_reset
70+
it ensures that the content of the state is written to the disk
71+
72+
#### ets_recovery
73+
it ensures that lru launches with prev state
74+
75+
#### tcp
76+
on or off support of ranch interaction, by default is off
77+
78+
#### mode
79+
mode work: inet|unix
80+
by default is inet
81+
82+
#### port
83+
port, by default 7777
84+
85+
#### ip
86+
ip, by default 127.0.0.1
87+
88+
#### unix
89+
unix_socket, by default '/var/run/lru/unix'
90+
91+
#### num_acceptors
92+
excerpt from 'ranch' documentation:
93+
94+
By default Ranch will use 10 acceptor processes. Their role is to accept connections and spawn a connection process for every new connection.
95+
This number can be tweaked to improve performance. A good number is typically between 10 or 100 acceptors. You must measure to find the best value for your application.
96+
97+
#### max_connections
98+
excerpt from 'ranch' documentation:
99+
100+
The max_connections transport option allows you to limit the number of concurrent connections per connection supervisor (see below).
101+
It defaults to 1024. Its purpose is to prevent your system from being overloaded and ensuring all the connections are handled optimally.
102+
103+
You can disable this limit by setting its value to the atom infinity.
104+
105+
The maximum number of connections is a soft limit. In practice, it can reach max_connections + the number of acceptors.
106+
107+
When the maximum number of connections is reached, Ranch will stop accepting connections.
108+
This will not result in further connections being rejected, as the kernel option allows queueing incoming connections.
109+
The size of this queue is determined by the backlog option and defaults to 1024. Ranch does not know about the number of connections that are in the backlog.
110+
111+
#### max_key_size
112+
max key size
113+
114+
## quick start
115+
#### like OTP application into your Erlang node
116+
117+
erl -config lru.config
118+
application:start(lru)
119+
120+
#### like daemon into your Unix-like OS
121+
122+
mkdir release
123+
tar -xf priv/lru.tar.gz -C release/
124+
125+
cp priv/init release/.
126+
cp priv/stop release/.
127+
128+
cd release
129+
130+
mkdir bin
131+
mkdir log
132+
mkdir pipe
133+
134+
cp erts-11.1/bin/start.src bin/start
135+
cp erts-11.1/bin/start_erl.src bin/start_erl
136+
cp erts-11.1/bin/run_erl bin/.
137+
cp erts-11.1/bin/to_erl bin/.
138+
cp erts-11.1/bin/erl bin/.
139+
cp erts-11.1/bin/heart bin/.
140+
cp erts-11.1/bin/escript bin/.
141+
142+
perl -i -pe "s#%FINAL_ROOTDIR%#$PWD#" bin/start
143+
144+
sed -i 's/\/tmp/$ROOTDIR\/pipe/' bin/start
145+
sed -i 's/\(.*run_erl.*\)".*$/\1 -sname lru -init_debug +t 10485760\"/' bin/start
146+
147+
echo "11.1 1" > releases/start_erl.data
148+
149+
./init startd
150+
./init stop
151+
152+
153+
## client interface
154+
###### This section describes two types interfaces:
155+
156+
internal - erlang interface for inner interaction in Erlang node
157+
external - outside interface for interaction from the world outside
158+
159+
#### put key
160+
###### internal:
161+
162+
lru:point(K). ok
163+
164+
###### external:
165+
166+
POINT:key %% "OK"
167+
168+
#### get counter on key
169+
###### internal:
170+
171+
lru:count(K). %% counter
172+
173+
###### external:
174+
175+
COUNT:key %% "NUMBER"
176+
177+
#### get oldest counter, current counter and quantity of keys
178+
###### internal:
179+
180+
lru:state(). %% [oldest counter,current counter,quantity of keys]
181+
182+
###### external:
183+
184+
STATE %% JSON: "{O:NUMBER,C:NUMBER,Q:NUMBER}"
185+
186+
#### store algorithm state to disk
187+
###### Please, pay attention 'store' call executes asynchronously!
188+
###### internal:
189+
190+
lru:store(). %% ok
191+
192+
###### external:
193+
194+
STORE %% "OK"
195+
196+
#### get oldest key and its counter
197+
198+
lru:fetch(). %% {counter,[<<"key">>]}
199+
200+
###### external:
201+
202+
FETCH %% JSON: "{counter:[key]}"
203+
204+
#### get and delete oldest key and its counter
205+
#### without confirm
206+
###### internal:
207+
208+
lru:clean(). %% {counter,[<<"key">>]}
209+
or
210+
lru:clean(async). %% {counter,[<<"key">>]}
211+
212+
###### external:
213+
214+
CLEAN %% JSON: "{counter:[key]}"
215+
or
216+
CLEAN:ASYNC %% JSON: "{counter:[key]}"
217+
218+
#### with confirm
219+
###### Please, pay attention timeout exists to confirm, equal '90' seconds by default
220+
###### internal:
221+
222+
{K,R} = lru:clean(sync). %% {{counter,[<<"key">>]},ref()}
223+
lru:clean(R,K). %% ok
224+
225+
###### external:
226+
227+
CLEAN:SYNC %% JSON: "{[{counter:[key]}]:UNIQ_REF}"
228+
CLEAN:UNIQ_REF %% "OK"
229+
230+
#### put list keys with conters
231+
###### initialization of state, for example, transfer of state from other implementation 'lru'
232+
###### internal:
233+
234+
lru:cheat([{K1,C1},{K2,C2},{K3,C3}]). %% ok
235+
236+
###### external:
237+
238+
CHEAT:key1,counter1;key2,counter2;key3,counter3 %% OK

0 commit comments

Comments
 (0)