source: trunk/libtransmission/peertree.h @ 2555

Last change on this file since 2555 was 2555, checked in by charles, 15 years ago

add portability wrapper for in_port_t...

  • Property svn:keywords set to Date Rev Author Id
File size: 4.2 KB
Line 
1/******************************************************************************
2 * $Id: peertree.h 2555 2007-07-30 18:04:10Z charles $
3 *
4 * Copyright (c) 2007 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#include "bsdtree.h"
26
27typedef struct tr_peertree_entry_s
28{
29    RB_ENTRY( tr_peertree_entry_s ) magic;
30    uint8_t peer[6];
31} tr_peertree_entry_t;
32
33typedef
34RB_HEAD( tr_peertree_s, tr_peertree_entry_s )
35tr_peertree_t;
36
37#define peertreeInit(tree)       RB_INIT(  (tree) )
38#define peertreeEmpty(tree)      RB_EMPTY( (tree) )
39#define peertreeFirst(tree)      RB_MIN(   tr_peertree_s, (tree) )
40#define peertreeNext(tree, item) RB_NEXT(  tr_peertree_s, (tree), (item) )
41#define peertreeFind(tree, item) RB_FIND(  tr_peertree_s, (tree), (item) )
42
43static int
44peertreekeycmp( tr_peertree_entry_t * aa, tr_peertree_entry_t * bb )
45{
46    return memcmp( aa->peer, bb->peer, 6 );
47}
48
49RB_GENERATE_STATIC( tr_peertree_s, tr_peertree_entry_s, magic, peertreekeycmp )
50
51static int
52peertreeCount( tr_peertree_t * tree )
53{
54    tr_peertree_entry_t * ii;
55    int                   count;
56
57    count = 0;
58    RB_FOREACH( ii, tr_peertree_s, tree )
59    {
60        count++;
61    }
62
63    return count;
64}
65
66static tr_peertree_entry_t *
67peertreeGet( tr_peertree_t * tree, struct in_addr * addr, tr_port_t port )
68{
69    tr_peertree_entry_t entry;
70
71    memset( &entry, 0, sizeof( entry ) );
72    memcpy( entry.peer, addr, 4 );
73    memcpy( entry.peer + 4, &port, 2 );
74
75    return RB_FIND( tr_peertree_s, tree, &entry );
76}
77
78static tr_peertree_entry_t *
79peertreeAdd( tr_peertree_t * tree, struct in_addr * addr, tr_port_t port )
80{
81    tr_peertree_entry_t * entry;
82
83    entry = calloc( 1, sizeof( *entry) );
84    if( NULL == entry )
85    {
86        return NULL;
87    }
88    memcpy( entry->peer, addr, 4 );
89    memcpy( entry->peer + 4, &port, 2 );
90    if( NULL == RB_INSERT( tr_peertree_s, tree, entry ) )
91    {
92        return entry;
93    }
94    free( entry );
95    return NULL;
96}
97
98static void
99peertreeMove( tr_peertree_t * dest, tr_peertree_t * src,
100              tr_peertree_entry_t * entry )
101{
102    tr_peertree_entry_t * sanity;
103
104    sanity = RB_REMOVE( tr_peertree_s, src, entry );
105    assert( sanity == entry );
106    sanity = RB_INSERT( tr_peertree_s, dest, entry );
107    assert( NULL == sanity );
108}
109
110static void
111peertreeMerge( tr_peertree_t * dest, tr_peertree_t * src )
112{
113    tr_peertree_entry_t * ii, * next, * sanity;
114
115    for( ii = peertreeFirst( src ); NULL != ii; ii = next )
116    {
117        next = peertreeNext( src, ii );
118        sanity = RB_REMOVE( tr_peertree_s, src, ii );
119        assert( sanity == ii );
120        sanity = RB_INSERT( tr_peertree_s, dest, ii );
121        assert( NULL == sanity );
122    }
123}
124
125static void
126peertreeSwap( tr_peertree_t * dest, tr_peertree_t * src )
127{
128    tr_peertree_t buf;
129
130    RB_ROOT( &buf ) = RB_ROOT( dest );
131    RB_ROOT( dest ) = RB_ROOT( src  );
132    RB_ROOT( src  ) = RB_ROOT( &buf );
133}
134
135static void
136peertreeFree( tr_peertree_t * tree )
137{
138    tr_peertree_entry_t * ii, * next;
139    for( ii = RB_MIN( tr_peertree_s, tree ); NULL != ii; ii = next )
140    {
141        next = RB_NEXT( tr_peertree_s, tree, ii );
142        RB_REMOVE( tr_peertree_s, tree, ii );
143        free( ii );
144    }
145}
Note: See TracBrowser for help on using the repository browser.