Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
RobotAPI
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Container Registry
Model registry
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Software
ArmarX
RobotAPI
Commits
2548003a
Commit
2548003a
authored
2 years ago
by
Rainer Kartmann
Browse files
Options
Downloads
Patches
Plain Diff
Revise interface of memory id lookups
parent
f9f57d48
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!244
Improve armem prediction interface
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
source/RobotAPI/libraries/armem/core/container_maps.h
+61
-38
61 additions, 38 deletions
source/RobotAPI/libraries/armem/core/container_maps.h
source/RobotAPI/libraries/armem/test/ArMemPrefixesTest.cpp
+24
-23
24 additions, 23 deletions
source/RobotAPI/libraries/armem/test/ArMemPrefixesTest.cpp
with
85 additions
and
61 deletions
source/RobotAPI/libraries/armem/core/container_maps.h
+
61
−
38
View file @
2548003a
...
@@ -32,10 +32,18 @@ namespace armarx::armem
...
@@ -32,10 +32,18 @@ namespace armarx::armem
namespace
detail
namespace
detail
{
{
template
<
class
KeyT
,
class
ValueT
>
struct
MapRef
{
KeyT
*
key
;
ValueT
*
value
;
};
/**
/**
* @brief Get the
key-value pair from
the map for which the returned key
* @brief Get the
entry in
the map for which the returned key
is the longest prefix
*
is the longest prefix
of the given key among the keys in the map.
* of the given key among the keys in the map.
*
*
* `prefixFunc` is used to successively calculate the prefixes of the given key.
* `prefixFunc` is used to successively calculate the prefixes of the given key.
* It must be pure and return an empty optional when there is no shorter
* It must be pure and return an empty optional when there is no shorter
...
@@ -44,35 +52,36 @@ namespace armarx::armem
...
@@ -44,35 +52,36 @@ namespace armarx::armem
* @param keyValMap the map that contains the key-value-pairs to search
* @param keyValMap the map that contains the key-value-pairs to search
* @param prefixFunc the function that returns the longest non-identical prefix of the key
* @param prefixFunc the function that returns the longest non-identical prefix of the key
* @param key the key to calculate the prefixes of
* @param key the key to calculate the prefixes of
*
* @return The iterator pointing to the found entry, or `keyValMap.end()`.
*/
*/
template
<
typename
KeyT
,
typename
ValueT
>
template
<
typename
KeyT
,
typename
ValueT
>
std
::
optional
<
std
::
pair
<
KeyT
,
ValueT
>
>
typename
std
::
map
<
KeyT
,
ValueT
>
::
const_iterator
get
WithLongestPrefix
(
const
std
::
map
<
KeyT
,
ValueT
>&
keyValMap
,
findEntry
WithLongestPrefix
(
const
std
::
map
<
KeyT
,
ValueT
>&
keyValMap
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
KeyT
&
)
>&
prefixFunc
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
KeyT
&
)
>&
prefixFunc
,
const
KeyT
&
key
)
const
KeyT
&
key
)
{
{
std
::
optional
<
KeyT
>
curKey
=
key
;
std
::
optional
<
KeyT
>
curKey
=
key
;
std
::
optional
<
ValueT
>
value
;
typename
std
::
map
<
KeyT
,
ValueT
>::
const_iterator
result
=
keyValMap
.
end
();
do
do
{
{
auto
iterator
=
keyValMap
.
find
(
curKey
.
value
());
auto
iterator
=
keyValMap
.
find
(
curKey
.
value
());
if
(
iterator
!=
keyValMap
.
end
())
if
(
iterator
!=
keyValMap
.
end
())
{
{
value
=
iterator
->
second
;
result
=
iterator
;
}
}
else
else
{
{
curKey
=
prefixFunc
(
curKey
.
value
());
curKey
=
prefixFunc
(
curKey
.
value
());
}
}
}
while
(
!
value
.
has_value
()
&&
curKey
.
has_value
());
if
(
value
.
has_value
())
{
return
{{
curKey
.
value
(),
value
.
value
()}};
}
}
return
{};
while
(
result
==
keyValMap
.
end
()
and
curKey
.
has_value
());
return
result
;
}
}
/**
/**
* @brief Accumulate all the values in a map for which the keys are prefixes of the given key.
* @brief Accumulate all the values in a map for which the keys are prefixes of the given key.
*
*
...
@@ -91,26 +100,27 @@ namespace armarx::armem
...
@@ -91,26 +100,27 @@ namespace armarx::armem
template
<
typename
KeyT
,
typename
ValueT
,
typename
AccumulateT
>
template
<
typename
KeyT
,
typename
ValueT
,
typename
AccumulateT
>
AccumulateT
AccumulateT
accumulateFromPrefixes
(
const
std
::
map
<
KeyT
,
ValueT
>&
keyValMap
,
accumulateFromPrefixes
(
const
std
::
map
<
KeyT
,
ValueT
>&
keyValMap
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
KeyT
&
)
>&
prefixFunc
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
const
KeyT
&
)
>&
prefixFunc
,
const
std
::
function
<
void
(
AccumulateT
&
,
ValueT
&
)
>
accumulateFunc
,
const
std
::
function
<
void
(
AccumulateT
&
,
const
ValueT
&
)
>
accumulateFunc
,
const
KeyT
&
key
)
const
KeyT
&
key
)
{
{
std
::
optional
<
KeyT
>
curKey
=
key
;
std
::
optional
<
KeyT
>
curKey
=
key
;
AccumulateT
values
;
AccumulateT
values
;
do
do
{
{
std
::
optional
<
std
::
pair
<
KeyT
,
ValueT
>>
nextPair
=
const
auto
nextEntry
=
get
WithLongestPrefix
<
KeyT
,
ValueT
>
(
keyValMap
,
prefixFunc
,
curKey
.
value
());
findEntry
WithLongestPrefix
<
KeyT
,
ValueT
>
(
keyValMap
,
prefixFunc
,
curKey
.
value
());
if
(
next
Pair
.
has_value
())
if
(
next
Entry
!=
keyValMap
.
end
())
{
{
curKey
=
prefixFunc
(
next
Pair
.
value
().
first
);
curKey
=
prefixFunc
(
next
Entry
->
first
);
accumulateFunc
(
values
,
next
Pair
.
value
().
second
);
accumulateFunc
(
values
,
next
Entry
->
second
);
}
}
else
else
{
{
curKey
.
reset
();
curKey
.
reset
();
}
}
}
while
(
curKey
.
has_value
());
}
while
(
curKey
.
has_value
());
return
values
;
return
values
;
}
}
...
@@ -129,13 +139,13 @@ namespace armarx::armem
...
@@ -129,13 +139,13 @@ namespace armarx::armem
template
<
typename
KeyT
,
typename
ValueT
>
template
<
typename
KeyT
,
typename
ValueT
>
std
::
vector
<
ValueT
>
std
::
vector
<
ValueT
>
accumulateFromPrefixes
(
const
std
::
map
<
KeyT
,
ValueT
>&
keyValMap
,
accumulateFromPrefixes
(
const
std
::
map
<
KeyT
,
ValueT
>&
keyValMap
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
KeyT
&
)
>&
prefixFunc
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
const
KeyT
&
)
>&
prefixFunc
,
const
KeyT
&
key
)
const
KeyT
&
key
)
{
{
return
accumulateFromPrefixes
<
KeyT
,
ValueT
,
std
::
vector
<
ValueT
>>
(
return
accumulateFromPrefixes
<
KeyT
,
ValueT
,
std
::
vector
<
ValueT
>>
(
keyValMap
,
keyValMap
,
prefixFunc
,
prefixFunc
,
[](
std
::
vector
<
ValueT
>&
values
,
ValueT
&
val
)
{
values
.
push_back
(
val
);
},
[](
std
::
vector
<
ValueT
>&
values
,
const
ValueT
&
val
)
{
values
.
push_back
(
val
);
},
key
);
key
);
}
}
...
@@ -153,57 +163,70 @@ namespace armarx::armem
...
@@ -153,57 +163,70 @@ namespace armarx::armem
template
<
typename
KeyT
,
typename
ValueT
>
template
<
typename
KeyT
,
typename
ValueT
>
std
::
vector
<
ValueT
>
std
::
vector
<
ValueT
>
accumulateFromPrefixes
(
const
std
::
map
<
KeyT
,
std
::
vector
<
ValueT
>>&
keyValMap
,
accumulateFromPrefixes
(
const
std
::
map
<
KeyT
,
std
::
vector
<
ValueT
>>&
keyValMap
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
KeyT
&
)
>&
prefixFunc
,
const
std
::
function
<
std
::
optional
<
KeyT
>
(
const
KeyT
&
)
>&
prefixFunc
,
const
KeyT
&
key
)
const
KeyT
&
key
)
{
{
return
accumulateFromPrefixes
<
KeyT
,
std
::
vector
<
ValueT
>
,
std
::
vector
<
ValueT
>>
(
return
accumulateFromPrefixes
<
KeyT
,
std
::
vector
<
ValueT
>
,
std
::
vector
<
ValueT
>>
(
keyValMap
,
keyValMap
,
prefixFunc
,
prefixFunc
,
[](
std
::
vector
<
ValueT
>&
values
,
std
::
vector
<
ValueT
>&
val
)
[](
std
::
vector
<
ValueT
>&
values
,
const
std
::
vector
<
ValueT
>&
val
)
{
values
.
insert
(
values
.
end
(),
val
.
begin
(),
val
.
end
());
},
{
values
.
insert
(
values
.
end
(),
val
.
begin
(),
val
.
end
());
},
key
);
key
);
}
}
}
// namespace detail
}
// namespace detail
std
::
optional
<
MemoryID
>
inline
getMemoryIDParent
(
MemoryID
&
memID
)
std
::
optional
<
MemoryID
>
inline
getMemoryIDParent
(
const
MemoryID
&
memID
)
{
{
if
(
!
memID
.
hasMemoryName
())
if
(
!
memID
.
hasMemoryName
())
{
{
return
{}
;
return
std
::
nullopt
;
}
}
MemoryID
parent
=
memID
.
removeLeafItem
();
MemoryID
parent
=
memID
.
removeLeafItem
();
return
{
parent
};
return
{
parent
};
}
}
/**
/**
* @see `getWithLongestPrefix`
* @brief Find the entry with the most specific key that contains the given ID,
* or `idMap.end()` if no key contains the ID.
*
* @see `detail::findEntryWithLongestPrefix()`
*/
*/
template
<
typename
ValueT
>
template
<
typename
ValueT
>
std
::
optional
<
std
::
pair
<
MemoryID
,
ValueT
>
>
typename
std
::
map
<
MemoryID
,
ValueT
>
::
const_iterator
getWith
MostSpecificContain
er
(
const
std
::
map
<
MemoryID
,
ValueT
>&
idMap
,
const
MemoryID
&
key
)
find
MostSpecific
Entry
Contain
ingID
(
const
std
::
map
<
MemoryID
,
ValueT
>&
idMap
,
const
MemoryID
&
id
)
{
{
return
detail
::
get
WithLongestPrefix
<
MemoryID
,
ValueT
>
(
idMap
,
&
getMemoryIDParent
,
key
);
return
detail
::
findEntry
WithLongestPrefix
<
MemoryID
,
ValueT
>
(
idMap
,
&
getMemoryIDParent
,
id
);
}
}
/**
/**
* @see `accumulateFromPrefixes`
* @brief Return all values of keys containing the given ID.
*
* @see `detail::accumulateFromPrefixes()`
*/
*/
template
<
typename
ValueT
>
template
<
typename
ValueT
>
std
::
vector
<
ValueT
>
std
::
vector
<
ValueT
>
accumulate
From
Contain
ers
(
const
std
::
map
<
MemoryID
,
ValueT
>&
idMap
,
const
MemoryID
&
key
)
accumulate
Entries
Contain
ingID
(
const
std
::
map
<
MemoryID
,
ValueT
>&
idMap
,
const
MemoryID
&
id
)
{
{
return
detail
::
accumulateFromPrefixes
<
MemoryID
,
ValueT
>
(
idMap
,
&
getMemoryIDParent
,
key
);
return
detail
::
accumulateFromPrefixes
<
MemoryID
,
ValueT
>
(
idMap
,
&
getMemoryIDParent
,
id
);
}
}
/**
/**
* @see `accumulateFromPrefixes`
* @brief Return all values of keys containing the given ID in a flattened vector.
*
* @see `detail::accumulateFromPrefixes()`
*/
*/
template
<
typename
ValueT
>
template
<
typename
ValueT
>
std
::
vector
<
ValueT
>
std
::
vector
<
ValueT
>
accumulate
From
Contain
ers
(
const
std
::
map
<
MemoryID
,
std
::
vector
<
ValueT
>>&
idMap
,
accumulate
Entries
Contain
ingID
(
const
std
::
map
<
MemoryID
,
std
::
vector
<
ValueT
>>&
idMap
,
const
MemoryID
&
key
)
const
MemoryID
&
key
)
{
{
return
detail
::
accumulateFromPrefixes
<
MemoryID
,
ValueT
>
(
idMap
,
&
getMemoryIDParent
,
key
);
return
detail
::
accumulateFromPrefixes
<
MemoryID
,
ValueT
>
(
idMap
,
&
getMemoryIDParent
,
key
);
}
}
}
// namespace armarx::armem
}
// namespace armarx::armem
This diff is collapsed.
Click to expand it.
source/RobotAPI/libraries/armem/test/ArMemPrefixesTest.cpp
+
24
−
23
View file @
2548003a
...
@@ -42,14 +42,13 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_prefixes)
...
@@ -42,14 +42,13 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_prefixes)
BOOST_TEST_CONTEXT
(
VAROUT
(
idMap
))
BOOST_TEST_CONTEXT
(
VAROUT
(
idMap
))
{
{
BOOST_CHECK
(
not
armem
::
getWith
MostSpecificContain
er
(
idMap
,
empty
)
.
has_value
());
BOOST_CHECK
(
armem
::
find
MostSpecific
Entry
Contain
ingID
(
idMap
,
empty
)
==
idMap
.
end
());
BOOST_CHECK
(
not
armem
::
getWith
MostSpecificContain
er
(
idMap
,
complete
)
.
has_value
());
BOOST_CHECK
(
armem
::
find
MostSpecific
Entry
Contain
ingID
(
idMap
,
complete
)
==
idMap
.
end
());
BOOST_CHECK
(
armem
::
accumulate
From
Contain
ers
(
idMap
,
empty
).
empty
());
BOOST_CHECK
(
armem
::
accumulate
Entries
Contain
ingID
(
idMap
,
empty
).
empty
());
BOOST_CHECK
(
armem
::
accumulate
From
Contain
ers
(
idMap
,
complete
).
empty
());
BOOST_CHECK
(
armem
::
accumulate
Entries
Contain
ingID
(
idMap
,
complete
).
empty
());
BOOST_CHECK
(
armem
::
accumulateEntriesContainingID
(
idListMap
,
empty
).
empty
());
BOOST_CHECK
(
armem
::
accumulateFromContainers
(
idListMap
,
empty
).
empty
());
BOOST_CHECK
(
armem
::
accumulateEntriesContainingID
(
idListMap
,
complete
).
empty
());
BOOST_CHECK
(
armem
::
accumulateFromContainers
(
idListMap
,
complete
).
empty
());
}
}
idMap
[
armem
::
MemoryID
()]
=
0
;
idMap
[
armem
::
MemoryID
()]
=
0
;
...
@@ -60,21 +59,23 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_prefixes)
...
@@ -60,21 +59,23 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_prefixes)
BOOST_TEST_CONTEXT
(
VAROUT
(
idMap
))
BOOST_TEST_CONTEXT
(
VAROUT
(
idMap
))
{
{
BOOST_CHECK
(
armem
::
getWithMostSpecificContainer
(
idMap
,
empty
)
auto
it
=
armem
::
findMostSpecificEntryContainingID
(
idMap
,
empty
);
.
value_or
(
std
::
make_pair
(
armem
::
MemoryID
(
"inv"
),
-
1
))
BOOST_CHECK
(
it
!=
idMap
.
end
());
.
second
==
0
);
BOOST_CHECK_EQUAL
(
it
->
second
,
0
);
BOOST_CHECK
(
armem
::
getWithMostSpecificContainer
(
idMap
,
complete
.
getCoreSegmentID
())
.
value_or
(
std
::
make_pair
(
armem
::
MemoryID
(
"inv"
),
-
1
))
it
=
armem
::
findMostSpecificEntryContainingID
(
idMap
,
complete
.
getCoreSegmentID
());
.
second
==
2
);
BOOST_CHECK
(
it
!=
idMap
.
end
());
BOOST_CHECK
(
armem
::
getWithMostSpecificContainer
(
idMap
,
complete
)
BOOST_CHECK_EQUAL
(
it
->
second
,
2
);
.
value_or
(
std
::
make_pair
(
armem
::
MemoryID
(
"inv"
),
-
1
))
.
second
==
3
);
it
=
armem
::
findMostSpecificEntryContainingID
(
idMap
,
complete
);
BOOST_CHECK
(
it
!=
idMap
.
end
());
BOOST_CHECK
((
armem
::
accumulateFromContainers
(
idMap
,
empty
)
==
std
::
vector
<
int
>
{
0
}));
BOOST_CHECK_EQUAL
(
it
->
second
,
3
);
BOOST_CHECK
((
armem
::
accumulateFromContainers
(
idMap
,
complete
.
getCoreSegmentID
())
==
BOOST_CHECK
((
armem
::
accumulateEntriesContainingID
(
idMap
,
empty
)
==
std
::
vector
<
int
>
{
0
}));
BOOST_CHECK
((
armem
::
accumulateEntriesContainingID
(
idMap
,
complete
.
getCoreSegmentID
())
==
std
::
vector
<
int
>
{
2
,
1
,
0
}));
std
::
vector
<
int
>
{
2
,
1
,
0
}));
BOOST_CHECK
(
BOOST_CHECK
(
(
armem
::
accumulate
From
Contain
ers
(
idMap
,
complete
)
==
std
::
vector
<
int
>
{
3
,
2
,
1
,
0
}));
(
armem
::
accumulate
Entries
Contain
ingID
(
idMap
,
complete
)
==
std
::
vector
<
int
>
{
3
,
2
,
1
,
0
}));
}
}
idListMap
.
emplace
(
"mem"
,
std
::
vector
<
int
>
{
1
,
2
});
idListMap
.
emplace
(
"mem"
,
std
::
vector
<
int
>
{
1
,
2
});
...
@@ -84,10 +85,10 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_prefixes)
...
@@ -84,10 +85,10 @@ BOOST_AUTO_TEST_CASE(test_MemoryID_prefixes)
BOOST_TEST_CONTEXT
(
VAROUT
(
idListMap
))
BOOST_TEST_CONTEXT
(
VAROUT
(
idListMap
))
{
{
BOOST_CHECK
((
armem
::
accumulate
From
Contain
ers
(
idListMap
,
empty
).
empty
()));
BOOST_CHECK
((
armem
::
accumulate
Entries
Contain
ingID
(
idListMap
,
empty
).
empty
()));
BOOST_CHECK
((
armem
::
accumulate
From
Contain
ers
(
idListMap
,
complete
.
getCoreSegmentID
())
==
BOOST_CHECK
((
armem
::
accumulate
Entries
Contain
ingID
(
idListMap
,
complete
.
getCoreSegmentID
())
==
std
::
vector
<
int
>
{
3
,
4
,
5
,
1
,
2
}));
std
::
vector
<
int
>
{
3
,
4
,
5
,
1
,
2
}));
BOOST_CHECK
((
armem
::
accumulate
From
Contain
ers
(
idListMap
,
complete
)
==
BOOST_CHECK
((
armem
::
accumulate
Entries
Contain
ingID
(
idListMap
,
complete
)
==
std
::
vector
<
int
>
{
6
,
7
,
8
,
3
,
4
,
5
,
1
,
2
}));
std
::
vector
<
int
>
{
6
,
7
,
8
,
3
,
4
,
5
,
1
,
2
}));
}
}
}
}
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