@@ -571,47 +571,75 @@ OpResult<string> OpIndex(const OpArgs& op_args, std::string_view key, long index
571
571
}
572
572
573
573
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) {
575
575
DCHECK (key.data () && element.data ());
576
+ DCHECK_NE (rank, 0 );
576
577
577
578
auto it_res = op_args.GetDbSlice ().FindReadOnly (op_args.db_cntx , key, OBJ_LIST);
578
579
if (!it_res.ok ())
579
580
return it_res.status ();
580
581
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 ;
593
583
vector<uint32_t > matches;
594
- string str;
595
584
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;
601
591
}
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
+ }
609
637
}
610
638
}
639
+ index++;
611
640
}
612
- index++ ;
641
+ quicklistReleaseIterator (ql_iter) ;
613
642
}
614
- quicklistReleaseIterator (ql_iter);
615
643
return matches;
616
644
}
617
645
@@ -624,29 +652,41 @@ OpResult<int> OpInsert(const OpArgs& op_args, string_view key, string_view pivot
624
652
if (!it_res)
625
653
return it_res.status ();
626
654
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 ;
631
656
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 ();
636
664
}
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 ;
638
670
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);
646
686
}
647
- res = quicklistCount (ql );
687
+ quicklistReleaseIterator (qiter );
648
688
}
649
- quicklistReleaseIterator (qiter);
689
+
650
690
return res;
651
691
}
652
692
@@ -738,14 +778,21 @@ OpStatus OpSet(const OpArgs& op_args, string_view key, string_view elem, long in
738
778
return it_res.status ();
739
779
740
780
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 );
744
789
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
+ }
747
794
}
748
- return OpStatus::OK ;
795
+ return status ;
749
796
}
750
797
751
798
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
803
850
if (!res)
804
851
return res.status ();
805
852
806
- quicklist* ql = GetQL ( res. value ( )->second ) ;
807
- long llen = quicklistCount (ql );
853
+ const PrimeValue& pv = (* res)->second ;
854
+ long llen = pv. Size ( );
808
855
809
856
/* convert negative indexes */
810
857
if (start < 0 )
@@ -823,13 +870,12 @@ OpResult<StringVec> OpRange(const OpArgs& op_args, std::string_view key, long st
823
870
824
871
StringVec str_vec;
825
872
container_utils::IterateList (
826
- res. value ()-> second ,
873
+ pv ,
827
874
[&str_vec](container_utils::ContainerEntry ce) {
828
875
str_vec.emplace_back (ce.ToString ());
829
876
return true ;
830
877
},
831
878
start, end);
832
-
833
879
return str_vec;
834
880
}
835
881
0 commit comments