int MMKVImpl::SRandMember(DBID db, const Data& key, const StringArrayResult& members, int count) { int err = 0; RWLockGuard<MemorySegmentManager, READ_LOCK> keylock_guard(m_segment); StringSet* set = GetObject<StringSet>(db, key, V_TYPE_SET, false, err)(); if (IS_NOT_EXISTS(err)) { return 0; } if (0 != err) { return err; } if (set->empty()) { return 0; } //return whole set if (count > 0 && count > set->size()) { StringSet::iterator it = set->begin(); while (it != set->end()) { it->ToString(members.Get()); it++; } return 0; } int rand = 0; for (int i = 0; i < std::abs(count); i++) { if (count > 0) { if (i == 0) { rand = random_between_int32(0, set->size() - 1); } else { rand += i; if (rand >= set->size()) { rand -= set->size(); } } } else { rand = random_between_int32(0, set->size() - 1); } StringSet::iterator it = set->begin(); it.increment_by(rand); it->ToString(members.Get()); } return 0; }
int64_t MMKVImpl::SScan(DBID db, const Data& key, int64_t cursor, const std::string& pattern, int32_t limit_count, const StringArrayResult& results) { int err = 0; RWLockGuard<MemorySegmentManager, READ_LOCK> keylock_guard(m_segment); StringSet* set = GetObject<StringSet>(db, key, V_TYPE_SET, false, err)(); if (NULL == set || 0 != err) { return err; } StringSet::iterator it = set->begin(); if (cursor >= set->size()) { return 0; } it.increment_by(cursor); int match_count = 0; while (it != set->end()) { std::string key_str; it->ToString(key_str); if (pattern == "" || stringmatchlen(pattern.c_str(), pattern.size(), key_str.c_str(), key_str.size(), 0) == 1) { std::string& ss = results.Get(); ss = key_str; match_count++; if (limit_count > 0 && match_count >= limit_count) { break; } } cursor++; it++; } return it != set->end() ? cursor : 0; }