Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
opendht
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
savoirfairelinux
opendht
Commits
8f5737a2
Unverified
Commit
8f5737a2
authored
8 years ago
by
kaldoran
Browse files
Options
Downloads
Patches
Plain Diff
Add some commentary
And move function around
parent
e2797284
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/opendht/indexation/pht.h
+70
-41
70 additions, 41 deletions
include/opendht/indexation/pht.h
src/indexation/pht.cpp
+55
-7
55 additions, 7 deletions
src/indexation/pht.cpp
with
125 additions
and
48 deletions
include/opendht/indexation/pht.h
+
70
−
41
View file @
8f5737a2
...
@@ -47,6 +47,18 @@ struct Prefix {
...
@@ -47,6 +47,18 @@ struct Prefix {
content_
.
push_back
(
p
.
content_
[
size_
/
8
]
&
(
0xFF
<<
(
8
-
rem
)));
content_
.
push_back
(
p
.
content_
[
size_
/
8
]
&
(
0xFF
<<
(
8
-
rem
)));
}
}
/**
* Get a sub prefix of the Prefix
*
* @param len lenght of the prefix to get, could be negative
* if len is negativ then you will get the prefix
* of size of the previous prefix minus len
*
* @return Sub-prefix of size len or if len is negative sub-prefix of size
* of prefix minus len
*
* @throw out_of_range if len is larger than size of the content
*/
Prefix
getPrefix
(
ssize_t
len
)
const
{
Prefix
getPrefix
(
ssize_t
len
)
const
{
if
((
size_t
)
std
::
abs
(
len
)
>=
content_
.
size
()
*
8
)
if
((
size_t
)
std
::
abs
(
len
)
>=
content_
.
size
()
*
8
)
throw
std
::
out_of_range
(
"len larger than prefix size."
);
throw
std
::
out_of_range
(
"len larger than prefix size."
);
...
@@ -57,16 +69,18 @@ struct Prefix {
...
@@ -57,16 +69,18 @@ struct Prefix {
}
}
/**
/**
* Method for getting the state of the bit at the position pos.
* Flags are considered as active if flag is empty or if the flag
* @param pos : Pos of the needed bit
* at pos 'pos' is active
* @return : true if the bit is at 1
ee *
* false otherwise
* @see isActiveBit in private function
* @throw out_of_range Throw out of range if the bit at 'pos' does not exist
*/
*/
bool
isFlagActive
(
size_t
pos
)
const
{
bool
isFlagActive
(
size_t
pos
)
const
{
return
flags_
.
empty
()
or
isActiveBit
(
flags_
,
pos
);
return
flags_
.
empty
()
or
isActiveBit
(
flags_
,
pos
);
}
}
/**
* @see isActiveBit in private function
*/
bool
isContentBitActive
(
size_t
pos
)
const
{
bool
isContentBitActive
(
size_t
pos
)
const
{
return
isActiveBit
(
content_
,
pos
);
return
isActiveBit
(
content_
,
pos
);
}
}
...
@@ -92,20 +106,6 @@ struct Prefix {
...
@@ -92,20 +106,6 @@ struct Prefix {
return
InfoHash
::
get
(
copy
);
return
InfoHash
::
get
(
copy
);
}
}
std
::
string
toString
()
const
{
std
::
stringstream
ss
;
ss
<<
"Prefix : "
<<
std
::
endl
<<
"
\t
Content_ : "
;
ss
<<
blobToString
(
content_
);
ss
<<
std
::
endl
;
ss
<<
"
\t
Flags_ : "
;
ss
<<
blobToString
(
flags_
);
ss
<<
std
::
endl
;
return
ss
.
str
();
}
/**
/**
* This method count total of bit in common between 2 prefix
* This method count total of bit in common between 2 prefix
*
*
...
@@ -141,63 +141,64 @@ struct Prefix {
...
@@ -141,63 +141,64 @@ struct Prefix {
return
8
*
i
+
j
;
return
8
*
i
+
j
;
}
}
/**
* @see doc of swap private function
*/
void
swapContentBit
(
size_t
bit
)
{
void
swapContentBit
(
size_t
bit
)
{
swapBit
(
content_
,
bit
);
swapBit
(
content_
,
bit
);
}
}
/**
/**
* This method swap the bit a the position 'bit'
* @see doc of swap private function
*
* @param bit Position of the bit to swap
* @return The prefix with the bit at position 'bit' swapped
* @throw out_of_range Throw out of range if bit does not exist
*/
*/
void
swapFlagBit
(
size_t
bit
)
{
void
swapFlagBit
(
size_t
bit
)
{
swapBit
(
flags_
,
bit
);
swapBit
(
flags_
,
bit
);
}
}
/**
* @see doc of addPadding private function
*/
void
addPaddingContent
(
size_t
size
)
{
void
addPaddingContent
(
size_t
size
)
{
content_
=
addPadding
(
content_
,
size
);
content_
=
addPadding
(
content_
,
size
);
}
}
void
updateFlags
()
{
void
updateFlags
()
{
/
/
Fill first known bit
/
*
Fill first known bit
*/
auto
csize
=
size_
-
flags_
.
size
()
*
8
;
auto
csize
=
size_
-
flags_
.
size
()
*
8
;
while
(
csize
>=
8
)
{
while
(
csize
>=
8
)
{
flags_
.
push_back
(
0xFF
);
flags_
.
push_back
(
0xFF
);
csize
-=
8
;
csize
-=
8
;
}
}
/
/
if needed fill remaining bit
/
*
if needed fill remaining bit
*/
if
(
csize
)
if
(
csize
)
flags_
.
push_back
(
0xFF
<<
(
8
-
csize
));
flags_
.
push_back
(
0xFF
<<
(
8
-
csize
));
/
/
Complet vector space missing
/
*
Complet vector space missing
*/
for
(
auto
i
=
flags_
.
size
();
i
<
content_
.
size
();
i
++
)
for
(
auto
i
=
flags_
.
size
();
i
<
content_
.
size
();
i
++
)
flags_
.
push_back
(
0xFF
);
flags_
.
push_back
(
0xFF
);
}
}
std
::
string
toString
()
const
;
size_t
size_
{
0
};
size_t
size_
{
0
};
/* Will contain flags according to content_.
If flags_[i] == 0, then content_[i] is unknown
else if flags_[i] == 1, then content_[i] is known */
Blob
flags_
{};
Blob
flags_
{};
Blob
content_
{};
Blob
content_
{};
private
:
private
:
std
::
string
blobToString
(
const
Blob
&
bl
)
const
{
/**
std
::
stringstream
ss
;
* Add a padding to the input blob
auto
bn
=
bl
.
size
()
%
8
;
*
auto
n
=
bl
.
size
()
/
8
;
* @param toP : Prefix where to add a padding
* @param size : Final size of the prefix with padding
for
(
size_t
i
=
0
;
i
<
bl
.
size
();
i
++
)
*
ss
<<
std
::
bitset
<
8
>
(
bl
[
i
])
<<
" "
;
* @return Copy of the input Blob but with a padding
if
(
bn
)
*/
for
(
unsigned
b
=
0
;
b
<
bn
;
b
++
)
ss
<<
(
char
)((
bl
[
n
]
&
(
1
<<
(
7
-
b
)))
?
'1'
:
'0'
);
return
ss
.
str
();
}
Blob
addPadding
(
Blob
toP
,
size_t
size
)
{
Blob
addPadding
(
Blob
toP
,
size_t
size
)
{
Blob
copy
=
toP
;
Blob
copy
=
toP
;
for
(
auto
i
=
copy
.
size
();
i
<
size
;
i
++
)
for
(
auto
i
=
copy
.
size
();
i
<
size
;
i
++
)
...
@@ -207,6 +208,16 @@ private:
...
@@ -207,6 +208,16 @@ private:
return
copy
;
return
copy
;
}
}
/**
* Check if the bit a pos 'pos' is active, i.e. equal to 1
*
* @param b : Blob to check
* @param pos : Position to check
*
* @return true if the bit is equal to 1, false otherwise
*
* @throw out_of_range if bit is superior to blob size * 8
*/
bool
isActiveBit
(
const
Blob
&
b
,
size_t
pos
)
const
{
bool
isActiveBit
(
const
Blob
&
b
,
size_t
pos
)
const
{
if
(
pos
>=
content_
.
size
()
*
8
)
if
(
pos
>=
content_
.
size
()
*
8
)
throw
std
::
out_of_range
(
"Can't detect active bit at pos, pos larger than prefix size or empty prefix"
);
throw
std
::
out_of_range
(
"Can't detect active bit at pos, pos larger than prefix size or empty prefix"
);
...
@@ -214,6 +225,16 @@ private:
...
@@ -214,6 +225,16 @@ private:
return
((
b
[
pos
/
8
]
>>
(
7
-
(
pos
%
8
))
)
&
1
)
==
1
;
return
((
b
[
pos
/
8
]
>>
(
7
-
(
pos
%
8
))
)
&
1
)
==
1
;
}
}
/**
* Swap bit at position bit [from 0 to 1 and vice-versa]
*
* @param b : Blob to swap
* @param bit : Bit to swap on b
*
* @return the input prefix with the bit at pos 'bit' swapped
*
* @throw out_of_range if bit is superior to blob size * 8
*/
void
swapBit
(
Blob
&
b
,
size_t
bit
)
{
void
swapBit
(
Blob
&
b
,
size_t
bit
)
{
if
(
bit
>=
b
.
size
()
*
8
)
if
(
bit
>=
b
.
size
()
*
8
)
throw
std
::
out_of_range
(
"bit larger than prefix size."
);
throw
std
::
out_of_range
(
"bit larger than prefix size."
);
...
@@ -259,6 +280,7 @@ public:
...
@@ -259,6 +280,7 @@ public:
/* A key for a an index entry */
/* A key for a an index entry */
using
Key
=
std
::
map
<
std
::
string
,
Blob
>
;
using
Key
=
std
::
map
<
std
::
string
,
Blob
>
;
/* Specifications of the keys. It defines the number, the length and the
/* Specifications of the keys. It defines the number, the length and the
* serialization order of fields. */
* serialization order of fields. */
using
KeySpec
=
std
::
map
<
std
::
string
,
size_t
>
;
using
KeySpec
=
std
::
map
<
std
::
string
,
size_t
>
;
...
@@ -397,6 +419,13 @@ private:
...
@@ -397,6 +419,13 @@ private:
std
::
shared_ptr
<
unsigned
>
max_common_prefix_len
,
std
::
shared_ptr
<
unsigned
>
max_common_prefix_len
,
int
start
=
-
1
,
bool
all_values
=
false
);
int
start
=
-
1
,
bool
all_values
=
false
);
/**
* Apply the zcurve algorithm on the list of input prefix
*
* @param all_prefix : Vector of prefix to interleave
*
* @return The output prefix where all flags and content are interleaves
*/
Prefix
zcurve
(
const
std
::
vector
<
Prefix
>&
all_prefix
)
const
;
Prefix
zcurve
(
const
std
::
vector
<
Prefix
>&
all_prefix
)
const
;
/**
/**
...
...
This diff is collapsed.
Click to expand it.
src/indexation/pht.cpp
+
55
−
7
View file @
8f5737a2
...
@@ -4,6 +4,41 @@
...
@@ -4,6 +4,41 @@
namespace
dht
{
namespace
dht
{
namespace
indexation
{
namespace
indexation
{
/**
* Output the blob into string and readable way
*
* @param bl : Blob to print
*
* @return string that represent the blob into a readable way
*/
static
std
::
string
blobToString
(
const
Blob
&
bl
)
{
std
::
stringstream
ss
;
auto
bn
=
bl
.
size
()
%
8
;
auto
n
=
bl
.
size
()
/
8
;
for
(
size_t
i
=
0
;
i
<
bl
.
size
();
i
++
)
ss
<<
std
::
bitset
<
8
>
(
bl
[
i
])
<<
" "
;
if
(
bn
)
for
(
unsigned
b
=
0
;
b
<
bn
;
b
++
)
ss
<<
(
char
)((
bl
[
n
]
&
(
1
<<
(
7
-
b
)))
?
'1'
:
'0'
);
return
ss
.
str
();
}
std
::
string
Prefix
::
toString
()
const
{
std
::
stringstream
ss
;
ss
<<
"Prefix : "
<<
std
::
endl
<<
"
\t
Content_ : "
;
ss
<<
blobToString
(
content_
);
ss
<<
std
::
endl
;
ss
<<
"
\t
Flags_ : "
;
ss
<<
blobToString
(
flags_
);
ss
<<
std
::
endl
;
return
ss
.
str
();
}
void
Pht
::
Cache
::
insert
(
const
Prefix
&
p
)
{
void
Pht
::
Cache
::
insert
(
const
Prefix
&
p
)
{
size_t
i
=
0
;
size_t
i
=
0
;
auto
now
=
clock
::
now
();
auto
now
=
clock
::
now
();
...
@@ -312,27 +347,39 @@ Prefix Pht::zcurve(const std::vector<Prefix>& all_prefix) const {
...
@@ -312,27 +347,39 @@ Prefix Pht::zcurve(const std::vector<Prefix>& all_prefix) const {
if
(
all_prefix
.
size
()
==
1
)
if
(
all_prefix
.
size
()
==
1
)
return
all_prefix
[
0
];
return
all_prefix
[
0
];
for
(
size_t
j
=
0
,
bit
=
0
;
j
<
all_prefix
[
0
].
content_
.
size
();
j
++
)
{
/* All prefix got the same size (thanks to padding) */
size_t
prefix_size
=
all_prefix
[
0
].
content_
.
size
();
/* Loop on all uint8_t of the input prefix */
for
(
size_t
j
=
0
,
bit
=
0
;
j
<
prefix_size
;
j
++
)
{
uint8_t
mask
=
0x80
;
uint8_t
mask
=
0x80
;
/* For each of the 8 bits of the input uint8_t */
for
(
int
i
=
0
;
i
<
8
;
)
{
for
(
int
i
=
0
;
i
<
8
;
)
{
uint8_t
flags
=
0
;
uint8_t
flags
=
0
;
uint8_t
content
=
0
;
uint8_t
content
=
0
;
for
(
int
k
=
0
;
k
<
8
;
k
++
,
bit
++
)
{
/* For each bit of the output uint8_t */
for
(
int
k
=
0
;
k
<
8
;
k
++
)
{
auto
diff
=
k
-
i
;
auto
diff
=
k
-
i
;
auto
x
=
all_prefix
[
bit
].
content_
[
j
]
&
mask
;
/*get the content 'c', and the flag 'f' of the input prefix */
auto
y
=
all_prefix
[
bit
].
flags_
[
j
]
&
mask
;
auto
c
=
all_prefix
[
bit
].
content_
[
j
]
&
mask
;
auto
f
=
all_prefix
[
bit
].
flags_
[
j
]
&
mask
;
content
|=
(
diff
>=
0
)
?
x
>>
diff
:
x
<<
std
::
abs
(
diff
);
/* Move this bit at the right position according to the diff
flags
|=
(
diff
>=
0
)
?
y
>>
diff
:
y
<<
std
::
abs
(
diff
);
and merge it into content and flags in the same way */
content
|=
(
diff
>=
0
)
?
c
>>
diff
:
c
<<
std
::
abs
(
diff
);
flags
|=
(
diff
>=
0
)
?
f
>>
diff
:
f
<<
std
::
abs
(
diff
);
if
(
bit
==
all_prefix
.
size
()
-
1
)
{
bit
=
-
1
;
++
i
;
mask
>>=
1
;
}
/* If we are on the last prefix of the vector get back to the first and
,move the mask in order to get the n + 1nth bit */
if
(
++
bit
==
all_prefix
.
size
()
)
{
bit
=
0
;
++
i
;
mask
>>=
1
;
}
}
}
/* Add the next flags + content to the output prefix */
p
.
content_
.
push_back
(
content
);
p
.
content_
.
push_back
(
content
);
p
.
flags_
.
push_back
(
flags
);
p
.
flags_
.
push_back
(
flags
);
p
.
size_
+=
8
;
p
.
size_
+=
8
;
...
@@ -348,6 +395,7 @@ Prefix Pht::linearize(Key k) const {
...
@@ -348,6 +395,7 @@ Prefix Pht::linearize(Key k) const {
std
::
vector
<
Prefix
>
all_prefix
;
std
::
vector
<
Prefix
>
all_prefix
;
all_prefix
.
reserve
(
k
.
size
());
all_prefix
.
reserve
(
k
.
size
());
/* Get the max size of the keyspec and take it for size limit (for padding) */
auto
max
=
std
::
max_element
(
keySpec_
.
begin
(),
keySpec_
.
end
(),
auto
max
=
std
::
max_element
(
keySpec_
.
begin
(),
keySpec_
.
end
(),
[](
const
std
::
pair
<
std
::
string
,
size_t
>&
a
,
const
std
::
pair
<
std
::
string
,
size_t
>&
b
)
{
[](
const
std
::
pair
<
std
::
string
,
size_t
>&
a
,
const
std
::
pair
<
std
::
string
,
size_t
>&
b
)
{
return
a
.
second
<
b
.
second
;
return
a
.
second
<
b
.
second
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment