Skip to content

Commit 38bad9e

Browse files
committed
chore: fully support qlist in all list commands
1 parent 0c710cd commit 38bad9e

File tree

1 file changed

+102
-56
lines changed

1 file changed

+102
-56
lines changed

src/server/list_family.cc

Lines changed: 102 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -571,47 +571,75 @@ OpResult<string> OpIndex(const OpArgs& op_args, std::string_view key, long index
571571
}
572572

573573
OpResult<vector<uint32_t>> OpPos(const OpArgs& op_args, string_view key, string_view element,
574-
int rank, int count, int max_len) {
574+
int rank, uint32_t count, uint32_t max_len) {
575575
DCHECK(key.data() && element.data());
576+
DCHECK_NE(rank, 0);
576577

577578
auto it_res = op_args.GetDbSlice().FindReadOnly(op_args.db_cntx, key, OBJ_LIST);
578579
if (!it_res.ok())
579580
return it_res.status();
580581

581-
int direction = AL_START_HEAD;
582-
if (rank < 0) {
583-
rank = -rank;
584-
direction = AL_START_TAIL;
585-
}
586-
587-
quicklist* ql = GetQL(it_res.value()->second);
588-
quicklistIter* ql_iter = quicklistGetIterator(ql, direction);
589-
quicklistEntry entry;
590-
591-
int index = 0;
592-
int matched = 0;
582+
const PrimeValue& pv = (*it_res)->second;
593583
vector<uint32_t> matches;
594-
string str;
595584

596-
while (quicklistNext(ql_iter, &entry) && (max_len == 0 || index < max_len)) {
597-
if (entry.value) {
598-
str.assign(reinterpret_cast<char*>(entry.value), entry.sz);
599-
} else {
600-
str = absl::StrCat(entry.longval);
585+
if (pv.Encoding() == kEncodingQL2) {
586+
QList* ql = GetQLV2(pv);
587+
QList::Where where = QList::HEAD;
588+
if (rank < 0) {
589+
rank = -rank;
590+
where = QList::TAIL;
601591
}
602-
if (str == element) {
603-
matched++;
604-
auto k = (direction == AL_START_TAIL) ? ql->count - index - 1 : index;
605-
if (matched >= rank) {
606-
matches.push_back(k);
607-
if (count && matched - rank + 1 >= count) {
608-
break;
592+
593+
auto it = ql->GetIterator(where);
594+
unsigned index = 0;
595+
while (it.Next() && (max_len == 0 || index < max_len)) {
596+
if (it.Get() == element) {
597+
if (rank == 1) {
598+
auto k = (where == QList::HEAD) ? index : ql->Size() - index - 1;
599+
matches.push_back(k);
600+
if (count && matches.size() >= count)
601+
break;
602+
} else {
603+
rank--;
604+
}
605+
}
606+
index++;
607+
}
608+
} else {
609+
int direction = AL_START_HEAD;
610+
if (rank < 0) {
611+
rank = -rank;
612+
direction = AL_START_TAIL;
613+
}
614+
615+
quicklist* ql = GetQL(it_res.value()->second);
616+
quicklistIter* ql_iter = quicklistGetIterator(ql, direction);
617+
quicklistEntry entry;
618+
619+
unsigned index = 0;
620+
int matched = 0;
621+
string str;
622+
623+
while (quicklistNext(ql_iter, &entry) && (max_len == 0 || index < max_len)) {
624+
if (entry.value) {
625+
str.assign(reinterpret_cast<char*>(entry.value), entry.sz);
626+
} else {
627+
str = absl::StrCat(entry.longval);
628+
}
629+
if (str == element) {
630+
matched++;
631+
auto k = (direction == AL_START_TAIL) ? ql->count - index - 1 : index;
632+
if (matched >= rank) {
633+
matches.push_back(k);
634+
if (count && unsigned(matched - rank + 1) >= count) {
635+
break;
636+
}
609637
}
610638
}
639+
index++;
611640
}
612-
index++;
641+
quicklistReleaseIterator(ql_iter);
613642
}
614-
quicklistReleaseIterator(ql_iter);
615643
return matches;
616644
}
617645

@@ -624,29 +652,41 @@ OpResult<int> OpInsert(const OpArgs& op_args, string_view key, string_view pivot
624652
if (!it_res)
625653
return it_res.status();
626654

627-
quicklist* ql = GetQL(it_res->it->second);
628-
quicklistEntry entry = container_utils::QLEntry();
629-
quicklistIter* qiter = quicklistGetIterator(ql, AL_START_HEAD);
630-
bool found = false;
655+
PrimeValue& pv = it_res->it->second;
631656

632-
while (quicklistNext(qiter, &entry)) {
633-
if (ElemCompare(entry, pivot)) {
634-
found = true;
635-
break;
657+
int res = -1;
658+
659+
if (pv.Encoding() == kEncodingQL2) {
660+
QList* ql = GetQLV2(pv);
661+
QList::InsertOpt insert_opt = (insert_param == INSERT_BEFORE) ? QList::BEFORE : QList::AFTER;
662+
if (ql->Insert(pivot, elem, insert_opt)) {
663+
res = ql->Size();
636664
}
637-
}
665+
} else {
666+
quicklist* ql = GetQL(pv);
667+
quicklistEntry entry = container_utils::QLEntry();
668+
quicklistIter* qiter = quicklistGetIterator(ql, AL_START_HEAD);
669+
bool found = false;
638670

639-
int res = -1;
640-
if (found) {
641-
if (insert_param == INSERT_AFTER) {
642-
quicklistInsertAfter(qiter, &entry, elem.data(), elem.size());
643-
} else {
644-
DCHECK_EQ(INSERT_BEFORE, insert_param);
645-
quicklistInsertBefore(qiter, &entry, elem.data(), elem.size());
671+
while (quicklistNext(qiter, &entry)) {
672+
if (ElemCompare(entry, pivot)) {
673+
found = true;
674+
break;
675+
}
676+
}
677+
678+
if (found) {
679+
if (insert_param == INSERT_AFTER) {
680+
quicklistInsertAfter(qiter, &entry, elem.data(), elem.size());
681+
} else {
682+
DCHECK_EQ(INSERT_BEFORE, insert_param);
683+
quicklistInsertBefore(qiter, &entry, elem.data(), elem.size());
684+
}
685+
res = quicklistCount(ql);
646686
}
647-
res = quicklistCount(ql);
687+
quicklistReleaseIterator(qiter);
648688
}
649-
quicklistReleaseIterator(qiter);
689+
650690
return res;
651691
}
652692

@@ -738,14 +778,21 @@ OpStatus OpSet(const OpArgs& op_args, string_view key, string_view elem, long in
738778
return it_res.status();
739779

740780
auto it = it_res->it;
741-
quicklist* ql = GetQL(it->second);
742-
743-
int replaced = quicklistReplaceAtIndex(ql, index, elem.data(), elem.size());
781+
OpStatus status = OpStatus::OUT_OF_RANGE;
782+
if (it->second.Encoding() == kEncodingQL2) {
783+
QList* ql = GetQLV2(it->second);
784+
if (ql->Replace(index, elem))
785+
status = OpStatus::OK;
786+
} else {
787+
DCHECK_EQ(it->second.Encoding(), OBJ_ENCODING_QUICKLIST);
788+
quicklist* ql = GetQL(it->second);
744789

745-
if (!replaced) {
746-
return OpStatus::OUT_OF_RANGE;
790+
int replaced = quicklistReplaceAtIndex(ql, index, elem.data(), elem.size());
791+
if (replaced) {
792+
status = OpStatus::OK;
793+
}
747794
}
748-
return OpStatus::OK;
795+
return status;
749796
}
750797

751798
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
803850
if (!res)
804851
return res.status();
805852

806-
quicklist* ql = GetQL(res.value()->second);
807-
long llen = quicklistCount(ql);
853+
const PrimeValue& pv = (*res)->second;
854+
long llen = pv.Size();
808855

809856
/* convert negative indexes */
810857
if (start < 0)
@@ -823,13 +870,12 @@ OpResult<StringVec> OpRange(const OpArgs& op_args, std::string_view key, long st
823870

824871
StringVec str_vec;
825872
container_utils::IterateList(
826-
res.value()->second,
873+
pv,
827874
[&str_vec](container_utils::ContainerEntry ce) {
828875
str_vec.emplace_back(ce.ToString());
829876
return true;
830877
},
831878
start, end);
832-
833879
return str_vec;
834880
}
835881

0 commit comments

Comments
 (0)