Handle HAVE_ALL and HAVE_NONE. Cleanup the BITFIELD message.
[etorrent.git] / lib / etorrent-1.0 / src / etorrent_tracking_map.erl
blob18ccaba30715ad8b6cd1b5c0a6c776d13094aa96
1 %%%-------------------------------------------------------------------
2 %%% File : etorrent_tracking_map.erl
3 %%% Author : Jesper Louis Andersen <>
4 %%% Description : Tracking Map manipulations
5 %%%
6 %%% Created : 15 Jun 2008 by Jesper Louis Andersen <>
7 %%%-------------------------------------------------------------------
8 -module(etorrent_tracking_map).
10 -include_lib("stdlib/include/qlc.hrl").
11 -include("etorrent_mnesia_table.hrl").
13 %% API
14 -export([all/0, new/3, delete/1, select/1, statechange/2,
15 is_ready_for_checking/1]).
17 %%====================================================================
18 %% API
19 %%====================================================================
20 %%--------------------------------------------------------------------
21 %% Function: new(Filename, Supervisor) -> ok
22 %% Description: Add a new torrent given by File with the Supervisor
23 %% pid as given to the database structure.
24 %%--------------------------------------------------------------------
25 new(File, Supervisor, Id) when is_integer(Id), is_pid(Supervisor), is_list(File) ->
26 mnesia:dirty_write(#tracking_map { id = Id,
27 filename = File,
28 supervisor_pid = Supervisor,
29 info_hash = unknown,
30 state = awaiting}).
32 %%--------------------------------------------------------------------
33 %% Function: all/0
34 %% Description: Return everything we are currently tracking
35 %%--------------------------------------------------------------------
36 all() ->
37 mnesia:transaction(
38 fun () ->
39 qlc:e(qlc:q([T || T <- mnesia:table(tracking_map)]))
40 end).
42 %%--------------------------------------------------------------------
43 %% Function: select(Id) -> [#tracking_map]
44 %% Args: Id ::= integer() | {filename, FN} | {infohash, IH}
46 %% FN ::= string()
47 %% IH ::= binary()
48 %% Description: Find tracking map matching the filename in question.
49 %%--------------------------------------------------------------------
50 select(Id) when is_integer(Id) ->
51 mnesia:transaction(
52 fun () ->
53 mnesia:read(tracking_map, Id, read)
54 end);
55 select({filename,Filename}) ->
56 mnesia:transaction(
57 fun () ->
58 Query = qlc:q([T || T <- mnesia:table(tracking_map),
59 T#tracking_map.filename == Filename]),
60 qlc:e(Query)
61 end);
62 select({infohash, InfoHash}) ->
63 mnesia:transaction(
64 fun () ->
65 Q = qlc:q([T || T <- mnesia:table(tracking_map),
66 T#tracking_map.info_hash =:= InfoHash]),
67 qlc:e(Q)
68 end).
70 %%--------------------------------------------------------------------
71 %% Function: delete(Id) -> ok
72 %% Description: Clean out all references to torrents matching Pid
73 %%--------------------------------------------------------------------
74 delete(Id) when is_integer(Id) ->
75 mnesia:dirty_delete(tracking_map, Id).
77 %%--------------------------------------------------------------------
78 %% Function: statechange(Id, What) -> ok
79 %% Description: Alter the state of the Tracking map identified by Id
80 %% by What (see alter_map/2).
81 %%--------------------------------------------------------------------
82 statechange(Id, What) ->
83 F = fun () ->
84 [TM] = mnesia:read(tracking_map, Id, write),
85 mnesia:write(alter_map(TM, What))
86 end,
87 {atomic, _} = mnesia:transaction(F),
88 ok.
90 %%--------------------------------------------------------------------
91 %% Function: is_ready_for_checking(Id) -> bool()
92 %% Description: Attempt to mark the torrent for checking. If this
93 %% succeeds, returns true, else false
94 %%--------------------------------------------------------------------
95 is_ready_for_checking(Id) ->
96 F = fun () ->
97 Q = qlc:q([TM || TM <- mnesia:table(tracking_map),
98 TM#tracking_map.state =:= checking]),
99 case length(qlc:e(Q)) of
100 0 ->
101 [TM] = mnesia:read(tracking_map, Id, write),
102 mnesia:write(TM#tracking_map { state = checking }),
103 true;
104 _ ->
105 false
107 end,
108 {atomic, T} = mnesia:transaction(F),
111 %%====================================================================
112 %% Internal functions
113 %%====================================================================
115 alter_map(TM, What) ->
116 case What of
117 {infohash, IH} ->
118 TM#tracking_map { info_hash = IH };
119 started ->
120 TM#tracking_map { state = started };
121 stopped ->
122 TM#tracking_map { state = stopped }
123 end.