Comments (9)
I don't think your example will compile because you made Foo::destroy
a static method, but your enqueue
function still expects a pointer to member.
Why not just make a member function that deletes itself? That seems to accomplish what you want.
struct Foo {
void destroy() {
delete this;
}
};
auto value= map.erase(key);
junction::DefaultQSBR.enqueue(&Foo::destroy, value);
from junction.
@preshing I'll be happy to send a pull request for this if you think it makes sense.
from junction.
That's is exactly what I'm doing currently, but object suicide is just doesn't look idiomatic :) My example might be a little crude but I'm sure we can make this work with any arbitrary function. I opened this to find out if there was any specific reason to restrict the function to be a member of the object.
from junction.
delete this
is legal: https://isocpp.org/wiki/faq/freestore-mgmt#delete-this
To answer your question, the callback is a member of an object:
- to avoid the need for a
void *
cast inside the callback - to avoid needing a virtual function
- because QSBR-managed classes are usually designed specifically for QSBR
- because it's easy to step into in Debug mode (compared to std::function)
Do you have a specific example where a different calling convention would offer a practical benefit over the current approach?
from junction.
@preshing I can use enqueue to destroy dynamic allocated object now? Can junction concurrent map support shared_ptr<V>
as value type? I appreciate your help, thank you very much!
Does this wrapper code is correct?I want know the Insert
and Clear
member function will work properly?
// K must integer type
template <typename K, typename V>
class LeapfrogMap {
public:
using ConcurrentMap = typename junction::ConcurrentMap_Leapfrog<K, V*>;
using MapIterator = typename ConcurrentMap::Iterator;
using MapMutator = typename ConcurrentMap::Mutator;
LeapfrogMap() {}
~LeapfrogMap() {}
// insert value only when not exist
template <typename... Args>
inline bool InsertOrFind(K key, V*& value, Args && ... args) {
value = m_hashMap.get(key);
if (!value) {
turf::LockGuard<turf::Mutex> lock(m_mutex);
MapMutator mutator = m_hashMap.insertOrFind(key);
value = mutator.getValue();
if (!value) {
value = new V(std::forward<Args>(args)...);
mutator.assignValue(value);
return true;
}
}
return false;
}
// upsert function
inline void Insert(K key, V* value) {
static_assert(std::is_integral<K>::value, "Key type must be integer.");
MapMutator mutator = m_hashMap.insertOrFind(key);
V* oldValue = mutator.exchangeValue(value);
if (oldValue != nullptr && oldValue != value) {
junction::DefaultQSBR.enqueue(&V::Destroy, oldValue);
}
}
inline bool Get(K key, V*& value) {
static_assert(std::is_integral<K>::value, "Key type must be integer.");
value = m_hashMap.get(key);
return value != nullptr;
}
inline void Delete(K key) {
static_assert(std::is_integral<K>::value, "Key type must be integer.");
V* oldValue = m_hashMap.erase(key);
if (oldValue != nullptr) {
junction::DefaultQSBR.enqueue(&V::Destroy, oldValue);
}
}
// 遍历比较耗时
inline void Clear() {
static_assert(std::is_integral<K>::value, "Key type must be integer.");
MapIterator mapIter(m_hashMap);
while (mapIter.isValid()) {
junction::DefaultQSBR.enqueue(&V::Destroy, mapIter.getValue());
m_hashMap.erase(mapIter.getKey());
mapIter.next();
}
}
// 遍历比较耗时
inline void DoFunc(std::function<void(K key, V* value)> func) {
if (func == nullptr) {
return;
}
static_assert(std::is_integral<K>::value, "Key type must be integer.");
MapIterator mapIter(m_hashMap);
while (mapIter.isValid()) {
func(mapIter.getKey(), mapIter.getValue());
mapIter.next();
}
}
// 对指定Key执行一段逻辑,如果满足条件就删除
inline void DoFuncThenDelete(const K& key, std::function<bool(V* value)> func) {
if (func == nullptr) {
return;
}
static_assert(std::is_integral<K>::value, "Key type must be integer.");
V* value = m_hashMap.get(key);
if (value != nullptr && func(value)) {
V* oldValue = m_hashMap.erase(key);
if (oldValue != nullptr) {
junction::DefaultQSBR.enqueue(&V::Destroy, oldValue);
}
}
}
private:
ConcurrentMap m_hashMap;
turf::Mutex m_mutex;
};
from junction.
Can junction concurrent map support shared_ptr as value type?
The answer to this question is still no at this time. Sorry!
from junction.
Thanks for your quick reply. Can you help me to check the wrapper code above, its Insert
and Clear
can work properly?
from junction.
Sure, I took a quick look. That code looks pretty sensible, however, it appears that you're using junction's QSBR to defer the destruction of each item in your map. To be honest, I didn't expect that kind of use for junction's QSBR. It's entirely possible that it works, but it might not be very scalable, because every call to QSBR::enqueue
involves a lock. But if you just want to gain more confidence that the code works as intended, it would help to write some multithreaded tests (similar to the tests already in junction). Ideally those tests would verify that all items were safely destroyed and their memory freed.
from junction.
Thank you very much,I have no idea how to safely destroy dynamic allocated object in the map,at this time i only can use the enqueue
method.
from junction.
Related Issues (20)
- Conan package
- Junction on ARM ? HOT 1
- bad_alloc in QSBR.h with Visual Studio
- BUG : Stucked while use mutator.getValue, but no error or exit. HOT 1
- Linker Errors: undefined reference to std::__cxx11::basic_string<>... HOT 2
- Junction as headers only HOT 1
- Limitations HOT 3
- Correct use of Garbage collection HOT 2
- Is there exist a fixed-size hash table's scenes ?
- Is it possible to get the smallest key in the map?
- Please document what source files are needed for those who want to do that way HOT 1
- how can i access all items in ConcurrentLeapfrogMap(or others) in parallel?
- How To use the object I defined as key in hashtable HOT 1
- How to use a non-number type as a key for maps (for example std::bitset)
- insertOrFind unexpected behavior HOT 3
- Currently using of iterator and assign.
- Coredump in turf heap free when TURF_REPLACE_OPERATOR_NEW=1
- sorry,please ignore and delete my issue
- Another type of key HOT 1
- How to process memory leak?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from junction.