add gen_todo.py script. include todo.html and mark up some todos in the code with priority

This commit is contained in:
Arvid Norberg 2013-01-20 23:21:53 +00:00
parent 360af45e63
commit f1b8582a95
18 changed files with 3752 additions and 30 deletions

View File

@ -9,6 +9,11 @@ libtorrent hacking
:depth: 2 :depth: 2
:backlinks: none :backlinks: none
This describe some of the internals of libtorrent. If you're looking for
something to contribute, please take a look at the `todo list`_.
.. _`todo list`: todo.html
terminology terminology
=========== ===========

3599
docs/todo.html Normal file

File diff suppressed because it is too large Load Diff

110
gen_todo.py Normal file
View File

@ -0,0 +1,110 @@
import glob
import os
paths = ['src/*.cpp', 'src/kademlia/*.cpp', 'include/libtorrent/*.hpp', 'include/libtorrent/kademlia/*.hpp', 'include/libtorrent/aux_/*.hpp', 'include/libtorrent/extensions/*.hpp']
os.system('ctags %s 2>/dev/null' % ' '.join(paths))
files = []
for p in paths:
files.extend(glob.glob(p))
items = []
# keeps 20 non-comment lines, used to get more context around
# todo-items
context = []
for f in files:
h = open(f)
state = ''
line_no = 0
context_lines = 0
for l in h:
line_no += 1
line = l.strip()
if 'TODO:' in line and line.startswith('//'):
line = line.split('TODO:')[1].strip()
state = 'todo'
items.append({})
items[-1]['location'] = '%s:%d' % (f, line_no)
items[-1]['priority'] = 0
if line[0] in '0123456789':
items[-1]['priority'] = int(line[0])
line = line[1:].strip()
items[-1]['todo'] = line
continue
if state == '':
context.append(l)
if len(context) > 20: context.pop(0)
continue
if state == 'todo':
if line.strip().startswith('//'):
items[-1]['todo'] += '\n'
items[-1]['todo'] += line[2:].strip()
else:
state = 'context'
items[-1]['context'] = ''.join(context) + '<div style="background: #ffff00" width="100%">' + l + '</div>';
context_lines = 1
continue
if state == 'context':
items[-1]['context'] += l
context_lines += 1
if context_lines > 30: state = ''
h.close()
items.sort(key = lambda x: x['priority'], reverse = True)
#for i in items:
# print '\n\n', i['todo'], '\n'
# print i['location'], '\n'
# print 'prio: ', i['priority'], '\n'
# if 'context' in i:
# print i['context'], '\n'
out = open('docs/todo.html', 'w+')
out.write('''<html><head>
<script type="text/javascript">
/* <![CDATA[ */
var expanded = -1
function expand(id) {
if (expanded != -1) {
var ctx = document.getElementById(expanded);
ctx.style.display = "none";
// if we're expanding the field that's already
// expanded, just collapse it
var no_expand = id == expanded;
expanded = -1;
if (no_expand) return;
}
var ctx = document.getElementById(id);
ctx.style.display = "table-row";
expanded = id;
}
/* ]]> */
</script>
</head><body>
<h1>libtorrent todo-list</h1>
<table width="100%" border="1" style="border-collapse: collapse;">''')
index = 0
for i in items:
if not 'context' in i: i['context'] = ''
out.write('<tr><td>relevance&nbsp;%d</td><td><a href="javascript:expand(%d)">%s</a></td><td>%s</td></tr>' \
% (i['priority'], index, i['location'], i['todo'].replace('\n', ' ')))
out.write('<tr id="%d" style="display: none;" colspan="3"><td colspan="3"><h2>%s</h2><h4>%s</h4><pre style="background: #f6f6f6; border: solid 1px #ddd;">%s</pre></td></tr>' \
% (index, i['todo'], i['location'], i['context']))
index += 1
out.write('</table></body></html>')
out.close()

View File

@ -57,7 +57,8 @@ class node_impl;
// -------- find data ----------- // -------- find data -----------
//TODO: rename this to find_peers //TODO: 3 rename this class to find_peers, since that's what it does
// find_data is an unnecessarily generic name
class find_data : public traversal_algorithm class find_data : public traversal_algorithm
{ {
public: public:

View File

@ -89,7 +89,9 @@ struct node_entry
else rtt = int(rtt) / 3 + int(new_rtt) * 2 / 3; else rtt = int(rtt) / 3 + int(new_rtt) * 2 / 3;
} }
// TODO: replace with a union of address_v4 and address_v6 // TODO: 2 replace with a union of address_v4 and address_v6
// to not waste space. This struct is instantiated hundreds of times
// for the routing table
address addr; address addr;
boost::uint16_t port; boost::uint16_t port;
// the number of times this node has failed to // the number of times this node has failed to

View File

@ -1035,7 +1035,10 @@ namespace libtorrent
}; };
// this list is sorted by time_critical_piece::deadline // this list is sorted by time_critical_piece::deadline
// TODO: this should be a deque // TODO: 2 this should be a deque, since time critical
// pieces are expected to be popped in the same order
// as they are sorted. The expectation is that new items
// are pushed back and items are popped from the front
std::list<time_critical_piece> m_time_critical_pieces; std::list<time_critical_piece> m_time_critical_pieces;
std::string m_trackerid; std::string m_trackerid;

View File

@ -371,10 +371,6 @@ namespace libtorrent
// when it was added. // when it was added.
std::string name() const; std::string name() const;
// TODO: add a feature where the user can tell the torrent
// to finish all pieces currently in the pipeline, and then
// abort the torrent.
void set_upload_limit(int limit) const; void set_upload_limit(int limit) const;
int upload_limit() const; int upload_limit() const;
void set_download_limit(int limit) const; void set_download_limit(int limit) const;

View File

@ -361,14 +361,16 @@ namespace libtorrent {
// system_time end = get_system_time() // system_time end = get_system_time()
// + boost::posix_time::microseconds(total_microseconds(max_wait)); // + boost::posix_time::microseconds(total_microseconds(max_wait));
// apparently this call can be interrupted // this call can be interrupted prematurely by other signals
// prematurely if there are other signals
// while (m_condition.timed_wait(lock, end)) // while (m_condition.timed_wait(lock, end))
// if (!m_alerts.empty()) return m_alerts.front(); // if (!m_alerts.empty()) return m_alerts.front();
ptime start = time_now_hires(); ptime start = time_now_hires();
// TODO: change this to use an asio timer instead // TODO: 3 change this to use a timed wait on a condition variable
// problem is, that's not necessarily portable. But it should be used
// where available. This implementation can be left the way it is for
// more primitive platforms
while (m_alerts.empty()) while (m_alerts.empty())
{ {
lock.unlock(); lock.unlock();

View File

@ -338,7 +338,6 @@ namespace libtorrent
// rely on default umask to filter x and w permissions // rely on default umask to filter x and w permissions
// for group and others // for group and others
// TODO: copy the mode from the source file
int permissions = S_IRUSR | S_IWUSR int permissions = S_IRUSR | S_IWUSR
| S_IRGRP | S_IWGRP | S_IRGRP | S_IWGRP
| S_IROTH | S_IWOTH; | S_IROTH | S_IWOTH;

View File

@ -117,7 +117,7 @@ namespace libtorrent
else else
{ {
int receive_buffer_size = receive_buffer().left() - m_parser.body_start(); int receive_buffer_size = receive_buffer().left() - m_parser.body_start();
// TODO: in chunked encoding mode, this assert won't hold // TODO: 1 in chunked encoding mode, this assert won't hold.
// the chunk headers should be subtracted from the receive_buffer_size // the chunk headers should be subtracted from the receive_buffer_size
TORRENT_ASSERT(receive_buffer_size <= t->block_size()); TORRENT_ASSERT(receive_buffer_size <= t->block_size());
ret.bytes_downloaded = t->block_size() - receive_buffer_size; ret.bytes_downloaded = t->block_size() - receive_buffer_size;

View File

@ -96,7 +96,7 @@ namespace libtorrent
void http_tracker_connection::start() void http_tracker_connection::start()
{ {
// TODO: authentication // TODO: 0 support authentication (i.e. user name and password) in the URL
std::string url = tracker_req().url; std::string url = tracker_req().url;
if (tracker_req().kind == tracker_request::scrape_request) if (tracker_req().kind == tracker_request::scrape_request)

View File

@ -33,7 +33,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/pch.hpp" #include "libtorrent/pch.hpp"
#include "libtorrent/socket.hpp" #include "libtorrent/socket.hpp"
// TODO: it would be nice to not have this dependency here // TODO: 3 remove this dependency by having the dht observer
// have its own flags
#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/aux_/session_impl.hpp"
#include <boost/bind.hpp> #include <boost/bind.hpp>

View File

@ -2485,7 +2485,7 @@ namespace libtorrent
TORRENT_ASSERT(m_ses.is_network_thread()); TORRENT_ASSERT(m_ses.is_network_thread());
// flush send buffer at the end of this scope // flush send buffer at the end of this scope
// TODO: peers should really be corked/uncorked outside of // TODO: 1 peers should really be corked/uncorked outside of
// all completed disk operations // all completed disk operations
cork _c(*this); cork _c(*this);

View File

@ -4082,7 +4082,6 @@ retry:
if (m_next_dht_torrent == m_torrents.end()) if (m_next_dht_torrent == m_torrents.end())
m_next_dht_torrent = m_torrents.begin(); m_next_dht_torrent = m_torrents.begin();
m_next_dht_torrent->second->dht_announce(); m_next_dht_torrent->second->dht_announce();
// TODO: make a list for torrents that want to be announced on the DHT
++m_next_dht_torrent; ++m_next_dht_torrent;
if (m_next_dht_torrent == m_torrents.end()) if (m_next_dht_torrent == m_torrents.end())
m_next_dht_torrent = m_torrents.begin(); m_next_dht_torrent = m_torrents.begin();
@ -4265,7 +4264,7 @@ retry:
bool handled_by_extension = false; bool handled_by_extension = false;
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
// TODO: allow extensions to sort torrents for queuing // TODO: 0 allow extensions to sort torrents for queuing
#endif #endif
if (!handled_by_extension) if (!handled_by_extension)
@ -6133,7 +6132,9 @@ retry:
// since we have a new external IP now, we need to // since we have a new external IP now, we need to
// restart the DHT with a new node ID // restart the DHT with a new node ID
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
// TODO: we only need to do this if our global IPv4 address has changed // TODO: 1 we only need to do this if our global IPv4 address has changed
// since the DHT (currently) only supports IPv4. Since restarting the DHT
// is kind of expensive, it would be nice to not do it unnecessarily
if (m_dht) if (m_dht)
{ {
entry s = m_dht->state(); entry s = m_dht->state();

View File

@ -986,7 +986,7 @@ ret:
size_type file_offset = start; size_type file_offset = start;
file_storage::iterator file_iter; file_storage::iterator file_iter;
// TODO: use binary search! // TODO: 3 use binary search to find the file entry
for (file_iter = files().begin();;) for (file_iter = files().begin();;)
{ {
if (file_offset < file_iter->size) if (file_offset < file_iter->size)
@ -1092,7 +1092,7 @@ ret:
size_type file_offset = start; size_type file_offset = start;
file_storage::iterator file_iter; file_storage::iterator file_iter;
// TODO: use binary search! // TODO: 3 use binary search to find the file entry
for (file_iter = files().begin();;) for (file_iter = files().begin();;)
{ {
if (file_offset < file_iter->size) if (file_offset < file_iter->size)
@ -1206,7 +1206,8 @@ ret:
// a specific alignment for writes. Make sure to truncate the size // a specific alignment for writes. Make sure to truncate the size
// TODO: what if file_base is used to merge several virtual files // TODO: what if file_base is used to merge several virtual files
// into a single physical file? // into a single physical file? We should probably disable this
// if file_base is used. This is not a widely used feature though
file_handle->set_size(file_iter->size, ec); file_handle->set_size(file_iter->size, ec);
} }
} }

View File

@ -4780,13 +4780,13 @@ namespace libtorrent
if (web->type == web_seed_entry::url_seed) if (web->type == web_seed_entry::url_seed)
{ {
c = new (std::nothrow) web_peer_connection( c = new (std::nothrow) web_peer_connection(
m_ses, shared_from_this(), s, a, web->url, &web->peer_info, // TODO: pass in web m_ses, shared_from_this(), s, a, web->url, &web->peer_info,
web->auth, web->extra_headers); web->auth, web->extra_headers);
} }
else if (web->type == web_seed_entry::http_seed) else if (web->type == web_seed_entry::http_seed)
{ {
c = new (std::nothrow) http_seed_connection( c = new (std::nothrow) http_seed_connection(
m_ses, shared_from_this(), s, a, web->url, &web->peer_info, // TODO: pass in web m_ses, shared_from_this(), s, a, web->url, &web->peer_info,
web->auth, web->extra_headers); web->auth, web->extra_headers);
} }
if (!c) return; if (!c) return;
@ -5291,7 +5291,8 @@ namespace libtorrent
, end(m_trackers.end()); i != end; ++i) , end(m_trackers.end()); i != end; ++i)
{ {
// don't save trackers we can't trust // don't save trackers we can't trust
// TODO: save the send_stats state instead // TODO: 1 save the send_stats state instead of throwing them away
// it may pose an issue when downgrading though
if (i->send_stats == false) continue; if (i->send_stats == false) continue;
if (i->tier == tier) if (i->tier == tier)
{ {
@ -5786,7 +5787,7 @@ namespace libtorrent
// failed to parse it. Pause the torrent // failed to parse it. Pause the torrent
if (alerts().should_post<metadata_failed_alert>()) if (alerts().should_post<metadata_failed_alert>())
{ {
// TODO: pass in ec along with the alert // TODO: 2 pass in ec along with the alert
alerts().post_alert(metadata_failed_alert(get_handle())); alerts().post_alert(metadata_failed_alert(get_handle()));
} }
set_error(errors::invalid_swarm_metadata, ""); set_error(errors::invalid_swarm_metadata, "");

View File

@ -545,9 +545,9 @@ namespace libtorrent
std::vector<peer_entry> peer_list; std::vector<peer_entry> peer_list;
for (int i = 0; i < num_peers; ++i) for (int i = 0; i < num_peers; ++i)
{ {
// TODO: don't use a string here. The problem is that // TODO: it would be more efficient to not use a string here.
// some trackers will respond with actual strings. // however, the problem is that some trackers will respond
// Especially i2p trackers // with actual strings. For example i2p trackers
peer_entry e; peer_entry e;
char ip_string[100]; char ip_string[100];
unsigned int a = detail::read_uint8(buf); unsigned int a = detail::read_uint8(buf);

View File

@ -409,9 +409,10 @@ struct utp_socket_impl
// timers when we should trigger the read and // timers when we should trigger the read and
// write callbacks (unless the buffers fill up // write callbacks (unless the buffers fill up
// before) // before)
// TODO: 3 remove the read timeout concept. This should not be necessary
ptime m_read_timeout; ptime m_read_timeout;
// TODO: remove the write timeout concept, and maybe even the read timeout // TODO: 3 remove the write timeout concept. This should not be necessary
ptime m_write_timeout; ptime m_write_timeout;
// the time when the last packet we sent times out. Including re-sends. // the time when the last packet we sent times out. Including re-sends.
@ -613,7 +614,7 @@ struct utp_socket_impl
bool m_attached:1; bool m_attached:1;
// this is true if nagle is enabled (which it is by default) // this is true if nagle is enabled (which it is by default)
// TODO: support the option to turn it off // TODO: 2 support the option to turn it off
bool m_nagle:1; bool m_nagle:1;
// this is true while the socket is in slow start mode. It's // this is true while the socket is in slow start mode. It's