void ZSetCache::GetRange(const ZRangeSpec& range, bool with_scores, bool with_attrs, ValueVisitCallback* cb, void* cbdata) { uint64 start = get_current_epoch_millis(); CacheReadLockGuard guard(m_lock); ZSetCaheElement min_ele(range.min.NumberValue(), ""); ZSetCaheElement max_ele(range.max.NumberValue(), ""); ZSetCacheElementSet::iterator min_it = m_cache.lower_bound(min_ele); ZSetCacheElementSet::iterator max_it = m_cache.lower_bound(max_ele); int cursor = 0; if (min_it != m_cache.end()) { while (!range.contain_min && min_it != m_cache.end() && min_it->score == range.min.NumberValue()) { min_it++; } while (range.contain_max && max_it != m_cache.end() && max_it->score == range.max.NumberValue()) { max_it++; } while (min_it != max_it && min_it != m_cache.end()) { ValueData v; Buffer buf(const_cast<char*>(min_it->value.data()), 0, min_it->value.size()); v.Decode(buf); cb(v, cursor++, cbdata); if (with_scores) { ValueData score; score.SetDoubleValue(min_it->score); cb(score, cursor++, cbdata); } if (with_attrs) { ValueData attr_value; Buffer attr_buf(const_cast<char*>(min_it->attr.data()), 0, min_it->attr.size()); attr_value.Decode(attr_buf); cb(attr_value, cursor++, cbdata); } min_it++; } } uint64 end = get_current_epoch_millis(); if (end - start > 10) { DEBUG_LOG("Cost %llums to get %d elements in between range [%.2f, %.2f]", end - start, cursor, range.min.NumberValue(), range.max.NumberValue()); } }
int ZSetCache::GetByValue(const ValueData& value, ValueData& score, ValueData& attr) { Buffer buf1; value.Encode(buf1); ZSetCaheElement e; e.value.assign(buf1.GetRawReadBuffer(), buf1.ReadableBytes()); CacheReadLockGuard guard(m_lock); ZSetCacheScoreMap::iterator sit = m_cache_score_dict.find(e.value); if (sit != m_cache_score_dict.end()) { e.score = sit->second; ZSetCacheElementSet::iterator found = m_cache.find(e); if (found != m_cache.end()) { score.SetDoubleValue(e.score); Buffer attr_buf(const_cast<char*>(found->attr.data()), 0, found->attr.size()); attr.Decode(attr_buf); return 0; } } return -1; }