Я предоставил две возможности. Тот, который вписывается в ваш дизайн, и тот, который вносит небольшое изменение в определение вашей записи. Посмотрите, какой из них лучше всего соответствует вашим потребностям. Первый ниже работает в вашем дизайне.
-record(user,{username,field1,field2,timestamp}).
%% execute the function below in a mnesia transaction
insert(#user{username = U,timestamp = _T} = User)->
case mnesia:read({user,U}) of
[] -> mnesia:write(User);
AllHere ->
case length(AllHere) == 500 of
false -> %% not yet 500
mnesia:write(User);
true ->
%% value has reached 500
%% get all timestamps and get the
%% oldest record and delete it
%%
OldRecord = get_oldest_stamp(AllHere),
ok = mnesia:delete_object(Record),
mnesia:write(User)
end
end.
get_oldest_stamp(UserRecords)->
%% here you do your sorting
%% and return the record with
%% oldest timestamp
....
OldRecord.
Функция length/1
в транзакции не является оптимальной. Давайте подумаем о лучшем пути. Кроме того, я не знаю, как выглядят ваши временные метки, поэтому я уверен, что у вас есть способ отсортировать их и узнать последнюю временную метку, выбрать запись, которой принадлежит эта временная метка, а затем вернуть ее. Я дал это решение просто для вашего дизайна. Я также думаю, что некоторые, где нам нужно немного indexing
. Следующая реализация кажется мне лучше. Например, если мы можем изменить определение записи, и мы вводим поле oldest
, которое принимает bool()
, и мы индексируем его следующим образом
-record(user,{
username,
field1,
field2,
timestamp,
oldest %% bool(), indexed<br> }).<br>
insert_user(Username,Field1,Field2)->
User = #user{
username = Username,
field1 = Field1,
field2 = Field2,
timestamp = {date(),time()}<br>
}.
insert(User).<br>
%% execute this within a mnesia transaction<br>
insert(#user{username = U} = User)->
case mnesia:read({user,U}) of
[] -> mnesia:write(User#user{oldest = true});
AllHere ->
case length(AllHere) == 500 of
false ->
%% unset all existing records' oldest field
%% to false
F = fun(UserX)->
ok = mnesia:delete_object(UserX),
ok = mnesia:write(UserX#user{oldest = false})
end,
[F(XX) || XX <- AllHere],
ok = mnesia:write(User#user{oldest = true});
true ->
[OldestRec] = mnesia:index_read(user,true,oldest),
ok = mnesia:delete_object(OldestRec),
ok = mnesia:write(User#user{oldest = true})
end
end.
Вышеприведенная реализация кажется мне лучше. успех !!