1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-14 11:58:02 +00:00

chore: fully support qlist in all list_family commands (#4201)

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2024-11-27 13:56:56 +02:00 committed by GitHub
parent 66e0fd0908
commit a87d6aecef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 105 additions and 58 deletions

View file

@ -133,7 +133,8 @@ jobs:
run: | run: |
cd ${GITHUB_WORKSPACE}/build cd ${GITHUB_WORKSPACE}/build
echo Run ctest -V -L DFLY echo Run ctest -V -L DFLY
GLOG_alsologtostderr=1 GLOG_vmodule=rdb_load=1,rdb_save=1,snapshot=1 timeout 20m ctest -V -L DFLY GLOG_alsologtostderr=1 GLOG_vmodule=rdb_load=1,rdb_save=1,snapshot=1 \
FLAGS_list_experimental_v2=true timeout 20m ctest -V -L DFLY
echo "Running tests with --force_epoll" echo "Running tests with --force_epoll"

View file

@ -571,13 +571,41 @@ OpResult<string> OpIndex(const OpArgs& op_args, std::string_view key, long index
} }
OpResult<vector<uint32_t>> OpPos(const OpArgs& op_args, string_view key, string_view element, OpResult<vector<uint32_t>> OpPos(const OpArgs& op_args, string_view key, string_view element,
int rank, int count, int max_len) { int rank, uint32_t count, uint32_t max_len) {
DCHECK(key.data() && element.data()); DCHECK(key.data() && element.data());
DCHECK_NE(rank, 0);
auto it_res = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key, OBJ_LIST); auto it_res = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key, OBJ_LIST);
if (!it_res.ok()) if (!it_res.ok())
return it_res.status(); return it_res.status();
const PrimeValue& pv = (*it_res)->second;
vector<uint32_t> matches;
if (pv.Encoding() == kEncodingQL2) {
QList* ql = GetQLV2(pv);
QList::Where where = QList::HEAD;
if (rank < 0) {
rank = -rank;
where = QList::TAIL;
}
auto it = ql->GetIterator(where);
unsigned index = 0;
while (it.Next() && (max_len == 0 || index < max_len)) {
if (it.Get() == element) {
if (rank == 1) {
auto k = (where == QList::HEAD) ? index : ql->Size() - index - 1;
matches.push_back(k);
if (count && matches.size() >= count)
break;
} else {
rank--;
}
}
index++;
}
} else {
int direction = AL_START_HEAD; int direction = AL_START_HEAD;
if (rank < 0) { if (rank < 0) {
rank = -rank; rank = -rank;
@ -588,9 +616,8 @@ OpResult<vector<uint32_t>> OpPos(const OpArgs& op_args, string_view key, string_
quicklistIter* ql_iter = quicklistGetIterator(ql, direction); quicklistIter* ql_iter = quicklistGetIterator(ql, direction);
quicklistEntry entry; quicklistEntry entry;
int index = 0; unsigned index = 0;
int matched = 0; int matched = 0;
vector<uint32_t> matches;
string str; string str;
while (quicklistNext(ql_iter, &entry) && (max_len == 0 || index < max_len)) { while (quicklistNext(ql_iter, &entry) && (max_len == 0 || index < max_len)) {
@ -604,7 +631,7 @@ OpResult<vector<uint32_t>> OpPos(const OpArgs& op_args, string_view key, string_
auto k = (direction == AL_START_TAIL) ? ql->count - index - 1 : index; auto k = (direction == AL_START_TAIL) ? ql->count - index - 1 : index;
if (matched >= rank) { if (matched >= rank) {
matches.push_back(k); matches.push_back(k);
if (count && matched - rank + 1 >= count) { if (count && unsigned(matched - rank + 1) >= count) {
break; break;
} }
} }
@ -612,6 +639,7 @@ OpResult<vector<uint32_t>> OpPos(const OpArgs& op_args, string_view key, string_
index++; index++;
} }
quicklistReleaseIterator(ql_iter); quicklistReleaseIterator(ql_iter);
}
return matches; return matches;
} }
@ -624,7 +652,18 @@ OpResult<int> OpInsert(const OpArgs& op_args, string_view key, string_view pivot
if (!it_res) if (!it_res)
return it_res.status(); return it_res.status();
quicklist* ql = GetQL(it_res->it->second); PrimeValue& pv = it_res->it->second;
int res = -1;
if (pv.Encoding() == kEncodingQL2) {
QList* ql = GetQLV2(pv);
QList::InsertOpt insert_opt = (insert_param == INSERT_BEFORE) ? QList::BEFORE : QList::AFTER;
if (ql->Insert(pivot, elem, insert_opt)) {
res = ql->Size();
}
} else {
quicklist* ql = GetQL(pv);
quicklistEntry entry = container_utils::QLEntry(); quicklistEntry entry = container_utils::QLEntry();
quicklistIter* qiter = quicklistGetIterator(ql, AL_START_HEAD); quicklistIter* qiter = quicklistGetIterator(ql, AL_START_HEAD);
bool found = false; bool found = false;
@ -636,7 +675,6 @@ OpResult<int> OpInsert(const OpArgs& op_args, string_view key, string_view pivot
} }
} }
int res = -1;
if (found) { if (found) {
if (insert_param == INSERT_AFTER) { if (insert_param == INSERT_AFTER) {
quicklistInsertAfter(qiter, &entry, elem.data(), elem.size()); quicklistInsertAfter(qiter, &entry, elem.data(), elem.size());
@ -647,6 +685,8 @@ OpResult<int> OpInsert(const OpArgs& op_args, string_view key, string_view pivot
res = quicklistCount(ql); res = quicklistCount(ql);
} }
quicklistReleaseIterator(qiter); quicklistReleaseIterator(qiter);
}
return res; return res;
} }
@ -738,14 +778,21 @@ OpStatus OpSet(const OpArgs& op_args, string_view key, string_view elem, long in
return it_res.status(); return it_res.status();
auto it = it_res->it; auto it = it_res->it;
OpStatus status = OpStatus::OUT_OF_RANGE;
if (it->second.Encoding() == kEncodingQL2) {
QList* ql = GetQLV2(it->second);
if (ql->Replace(index, elem))
status = OpStatus::OK;
} else {
DCHECK_EQ(it->second.Encoding(), OBJ_ENCODING_QUICKLIST);
quicklist* ql = GetQL(it->second); quicklist* ql = GetQL(it->second);
int replaced = quicklistReplaceAtIndex(ql, index, elem.data(), elem.size()); int replaced = quicklistReplaceAtIndex(ql, index, elem.data(), elem.size());
if (replaced) {
if (!replaced) { status = OpStatus::OK;
return OpStatus::OUT_OF_RANGE;
} }
return OpStatus::OK; }
return status;
} }
OpStatus OpTrim(const OpArgs& op_args, string_view key, long start, long end) { OpStatus OpTrim(const OpArgs& op_args, string_view key, long start, long end) {
@ -803,8 +850,8 @@ OpResult<StringVec> OpRange(const OpArgs& op_args, std::string_view key, long st
if (!res) if (!res)
return res.status(); return res.status();
quicklist* ql = GetQL(res.value()->second); const PrimeValue& pv = (*res)->second;
long llen = quicklistCount(ql); long llen = pv.Size();
/* convert negative indexes */ /* convert negative indexes */
if (start < 0) if (start < 0)
@ -823,13 +870,12 @@ OpResult<StringVec> OpRange(const OpArgs& op_args, std::string_view key, long st
StringVec str_vec; StringVec str_vec;
container_utils::IterateList( container_utils::IterateList(
res.value()->second, pv,
[&str_vec](container_utils::ContainerEntry ce) { [&str_vec](container_utils::ContainerEntry ce) {
str_vec.emplace_back(ce.ToString()); str_vec.emplace_back(ce.ToString());
return true; return true;
}, },
start, end); start, end);
return str_vec; return str_vec;
} }