Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
defunctec
crown-core
Commits
12444942
Commit
12444942
authored
13 years ago
by
Pieter Wuille
Browse files
Options
Download
Email Patches
Plain Diff
Add mruset and use it for setInventoryKnown
parent
79ce6d55
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
bitcoin-qt.pro
+1
-0
bitcoin-qt.pro
src/mruset.h
+63
-0
src/mruset.h
src/net.h
+3
-1
src/net.h
src/test/mruset_tests.cpp
+90
-0
src/test/mruset_tests.cpp
with
157 additions
and
1 deletion
+157
-1
bitcoin-qt.pro
View file @
12444942
...
...
@@ -118,6 +118,7 @@ HEADERS += src/qt/bitcoingui.h \
src
/
init
.
h
\
src
/
headers
.
h
\
src
/
irc
.
h
\
src
/
mruset
.
h
\
src
/
json
/
json_spirit_writer_template
.
h
\
src
/
json
/
json_spirit_writer
.
h
\
src
/
json
/
json_spirit_value
.
h
\
...
...
This diff is collapsed.
Click to expand it.
src/mruset.h
0 → 100644
View file @
12444942
// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MRUSET_H
#define BITCOIN_MRUSET_H
#include <set>
#include <deque>
template
<
typename
T
>
class
mruset
{
public:
typedef
T
key_type
;
typedef
T
value_type
;
typedef
typename
std
::
set
<
T
>::
iterator
iterator
;
typedef
typename
std
::
set
<
T
>::
const_iterator
const_iterator
;
typedef
typename
std
::
set
<
T
>::
size_type
size_type
;
protected:
std
::
set
<
T
>
set
;
std
::
deque
<
T
>
queue
;
size_type
nMaxSize
;
public:
mruset
(
size_type
nMaxSizeIn
=
0
)
{
nMaxSize
=
nMaxSizeIn
;
}
iterator
begin
()
const
{
return
set
.
begin
();
}
iterator
end
()
const
{
return
set
.
end
();
}
size_type
size
()
const
{
return
set
.
size
();
}
bool
empty
()
const
{
return
set
.
empty
();
}
iterator
find
(
const
key_type
&
k
)
const
{
return
set
.
find
(
k
);
}
size_type
count
(
const
key_type
&
k
)
const
{
return
set
.
count
(
k
);
}
bool
inline
friend
operator
==
(
const
mruset
<
T
>&
a
,
const
mruset
<
T
>&
b
)
{
return
a
.
set
==
b
.
set
;
}
bool
inline
friend
operator
==
(
const
mruset
<
T
>&
a
,
const
std
::
set
<
T
>&
b
)
{
return
a
.
set
==
b
;
}
bool
inline
friend
operator
<
(
const
mruset
<
T
>&
a
,
const
mruset
<
T
>&
b
)
{
return
a
.
set
<
b
.
set
;
}
std
::
pair
<
iterator
,
bool
>
insert
(
const
key_type
&
x
)
{
std
::
pair
<
iterator
,
bool
>
ret
=
set
.
insert
(
x
);
if
(
ret
.
second
)
{
if
(
nMaxSize
&&
queue
.
size
()
==
nMaxSize
)
{
set
.
erase
(
queue
.
front
());
queue
.
pop_front
();
}
queue
.
push_back
(
x
);
}
return
ret
;
}
size_type
max_size
()
const
{
return
nMaxSize
;
}
size_type
max_size
(
size_type
s
)
{
if
(
s
)
while
(
queue
.
size
()
>=
s
)
{
set
.
erase
(
queue
.
front
());
queue
.
pop_front
();
}
nMaxSize
=
s
;
return
nMaxSize
;
}
};
#endif
This diff is collapsed.
Click to expand it.
src/net.h
View file @
12444942
...
...
@@ -14,6 +14,7 @@
#include <arpa/inet.h>
#endif
#include "mruset.h"
#include "netbase.h"
#include "protocol.h"
...
...
@@ -154,7 +155,7 @@ public:
std
::
set
<
uint256
>
setKnown
;
// inventory based relay
std
::
set
<
CInv
>
setInventoryKnown
;
mru
set
<
CInv
>
setInventoryKnown
;
std
::
vector
<
CInv
>
vInventoryToSend
;
CCriticalSection
cs_inventory
;
std
::
multimap
<
int64
,
CInv
>
mapAskFor
;
...
...
@@ -193,6 +194,7 @@ public:
fGetAddr
=
false
;
vfSubscribe
.
assign
(
256
,
false
);
nMisbehavior
=
0
;
setInventoryKnown
.
max_size
(
SendBufferSize
()
/
1000
);
// Be shy and don't send version until we hear
if
(
!
fInbound
)
...
...
This diff is collapsed.
Click to expand it.
src/test/mruset_tests.cpp
0 → 100644
View file @
12444942
#include <boost/test/unit_test.hpp>
using
namespace
std
;
#include "mruset.h"
#include "util.h"
#define NUM_TESTS 16
#define MAX_SIZE 100
class
mrutester
{
private:
mruset
<
int
>
mru
;
std
::
set
<
int
>
set
;
public:
mrutester
()
{
mru
.
max_size
(
MAX_SIZE
);
}
int
size
()
const
{
return
set
.
size
();
}
void
insert
(
int
n
)
{
mru
.
insert
(
n
);
set
.
insert
(
n
);
BOOST_CHECK
(
mru
==
set
);
}
};
BOOST_AUTO_TEST_SUITE
(
mruset_tests
)
// Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it
BOOST_AUTO_TEST_CASE
(
mruset_like_set
)
{
for
(
int
nTest
=
0
;
nTest
<
NUM_TESTS
;
nTest
++
)
{
mrutester
tester
;
while
(
tester
.
size
()
<
MAX_SIZE
)
tester
.
insert
(
GetRandInt
(
2
*
MAX_SIZE
));
}
}
// Test that an mruset's size never exceeds its max_size
BOOST_AUTO_TEST_CASE
(
mruset_limited_size
)
{
for
(
int
nTest
=
0
;
nTest
<
NUM_TESTS
;
nTest
++
)
{
mruset
<
int
>
mru
(
MAX_SIZE
);
for
(
int
nAction
=
0
;
nAction
<
3
*
MAX_SIZE
;
nAction
++
)
{
int
n
=
GetRandInt
(
2
*
MAX_SIZE
);
mru
.
insert
(
n
);
BOOST_CHECK
(
mru
.
size
()
<=
MAX_SIZE
);
}
}
}
// 16-bit permutation function
int
static
permute
(
int
n
)
{
// hexadecimals of pi; verified to be linearly independent
static
const
int
table
[
16
]
=
{
0x243F
,
0x6A88
,
0x85A3
,
0x08D3
,
0x1319
,
0x8A2E
,
0x0370
,
0x7344
,
0xA409
,
0x3822
,
0x299F
,
0x31D0
,
0x082E
,
0xFA98
,
0xEC4E
,
0x6C89
};
int
ret
=
0
;
for
(
int
bit
=
0
;
bit
<
16
;
bit
++
)
if
(
n
&
(
1
<<
bit
))
ret
^=
table
[
bit
];
return
ret
;
}
// Test that an mruset acts like a moving window, if no duplcate elements are added
BOOST_AUTO_TEST_CASE
(
mruset_window
)
{
mruset
<
int
>
mru
(
MAX_SIZE
);
for
(
int
n
=
0
;
n
<
10
*
MAX_SIZE
;
n
++
)
{
mru
.
insert
(
permute
(
n
));
set
<
int
>
tester
;
for
(
int
m
=
max
(
0
,
n
-
MAX_SIZE
+
1
);
m
<=
n
;
m
++
)
tester
.
insert
(
permute
(
m
));
BOOST_CHECK
(
mru
==
tester
);
}
}
BOOST_AUTO_TEST_SUITE_END
()
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment