size_t count(void) { Lock(); size_t ret = InternalList.size(); Unlock(); return (ret); };
size_t get_nodes(NodeListT &out) { Lock(); out = InternalList; Unlock(); return (out.size()); };
size_t pick(const hashT &target, NodeListT &dest, size_t limit) { //stopwatch sw("pick"); typedef std::map<hashT,T*> SortedNodePListT; SortedNodePListT sorted_list; Lock(); { typename NodeListT::iterator it = InternalList.begin(); for ( ; it != InternalList.end(); it++) { hashT _xor; hash_xor(_xor, target, it->id); sorted_list.insert(typename SortedNodePListT::value_type(_xor, &(*it))); } size_t i = 0; typename SortedNodePListT::iterator sit = sorted_list.begin(); for ( ; sit != sorted_list.end() && i < limit; sit++, i++) { dest.push_back(*(sit->second)); } } Unlock(); return (dest.size()); };
bool push(const T &node) { if (!node.valid()) return false; bool proceeded = false; Lock(); { typename NodeListT::iterator it; it = std::find(InternalList.begin(), InternalList.end(), node); if (it != InternalList.end()) { //既存なら最後尾へ T mnode(*it); InternalList.erase(it); mnode.marge(node); mnode.lastlink = time(NULL); InternalList.push_back(mnode); proceeded = true; } else if (InternalList.size() < Capacity) { //リストに余裕があるなら最後尾に追加 T newnode(node); newnode.lastlink = time(NULL); InternalList.push_back(newnode); proceeded = true; } #if !USEPING else { pop_front(); T newnode(node); newnode.lastlink = time(NULL); InternalList.push_back(newnode); proceeded = true; } #endif } Unlock(); #if USEPING if (proceeded) return true; //リストの一番上のノード=最古ノードの生存確認 T head; get_front(head); bool alive = ping(head); if (alive) { //最古ノードが生きている:最古ノードを最後尾へ //※対象ノードは追加しない pop_front(); head.lastlink = time(NULL); Lock(); InternalList.push_back(head); Unlock(); } else { //最古ノードが死んでいる:対象ノードを最後尾に追加 pop_front(); T newnode(node); newnode.lastlink = time(NULL); Lock(); InternalList.push_back(newnode); Unlock(); } #endif return true; };