编写一种键->值存储,让它把较小的值放入内存,把较大的值放入磁盘。制作一个适配器模块来实现它,并让这个模块与本章前面的适配器具有相同的接口。
1 使用dict存数据
-module(adapter_db3).
-export([new/0, store/3, lookup/2, close/1]).
new() ->
{?MODULE, dict:new(), []}.
store(Key, Val, {?MODULE, MemDict, DiskList}) when Val < 5000 ->
MemDict1 = dict:store(Key, Val, MemDict),
{?MODULE, MemDict1, DiskList};
store(Key, Val, {?MODULE, MemDict, DiskList}) ->
DiskList1 = lists:keystore(Key, 1, DiskList, {Key, Val}),
{?MODULE, MemDict, DiskList1}.
lookup(Key, {?MODULE, MemDict, DiskList}) ->
case dict:find(Key, MemDict) of
{ok, Val} ->
{ok, Val};
error ->
case lists:keysearch(Key, 1, DiskList) of
{value, {Key, Val}} ->
{ok, Val};
false ->
error
end
end.
close({?MODULE, _MemDict, DiskList}) ->
case dets:open_file(data_db, [{keypos, 1}, {auto_save, 5000}]) of
{ok, Tab} ->
[dets:insert(Tab, {K, V}) || {K, V} <- DiskList],
dets:sync(Tab),
dets:close(Tab),
ok;
{error, Reason} ->
{error, Reason}
end.
2 使用ets存数据
-module(adapter_db3).
-export([new/0, store/3, lookup/2, close/1]).
new() ->
{?MODULE, ets:new(?MODULE, [named_table, public]), []}.
store(Key, Val, {?MODULE, MemTable, DiskList}) when Val < 5000 ->
MemTable1 = ets:insert(MemTable, {Key, Val}),
{?MODULE, MemTable1, DiskList};
store(Key, Val, {?MODULE, MemTable, DiskList}) ->
DiskList1 = lists:keystore(Key, 1, DiskList, {Key, Val}),
{?MODULE, MemTable, DiskList1}.
lookup(Key, {?MODULE, MemTable, DiskList}) ->
case ets:lookup(MemTable, Key) of
[{Key, Val}] ->
{ok, Val};
[] ->
case lists:keysearch(Key, 1, DiskList) of
{value, {Key, Val}} ->
{ok, Val};
false ->
error
end
end.
close({?MODULE, _MemTable, DiskList}) ->
case dets:open_file(data_db, [{keypos, 1}, {auto_save, 5000}]) of
{ok, Tab} ->
[dets:insert(Tab, {K, V}) || {K, V} <- DiskList],
dets:close(Tab),
ok;
{error, Reason} ->
{error, Reason}
end.