@@ -32,6 +32,9 @@ static uint8_t kMongocEmptyBson[] = { 5, 0, 0, 0, 0 };
32
32
33
33
static bson_oid_t kObjectIdZero = { {0 } };
34
34
35
+ static bool _match_tag_set (const mongoc_server_description_t * sd ,
36
+ bson_iter_t * tag_set_iter );
37
+
35
38
/* Destroy allocated resources within @description, but don't free it */
36
39
void
37
40
mongoc_server_description_cleanup (mongoc_server_description_t * sd )
@@ -734,10 +737,10 @@ mongoc_server_description_filter_stale (mongoc_server_description_t **sds,
734
737
*
735
738
* mongoc_server_description_filter_tags --
736
739
*
737
- * Given a set of server descriptions, determine have the correct tags
738
- * as per the Server Selection spec. Determines the number of
739
- * eligible servers, and sets any servers that are NOT eligible to
740
- * NULL in the descriptions set.
740
+ * Given a set of server descriptions, set to NULL any that don't
741
+ * match the the read preference's tag sets.
742
+ *
743
+ * https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#tag-set
741
744
*
742
745
*-------------------------------------------------------------------------
743
746
*/
@@ -749,14 +752,9 @@ mongoc_server_description_filter_tags (mongoc_server_description_t **description
749
752
{
750
753
const bson_t * rp_tags ;
751
754
bson_iter_t rp_tagset_iter ;
752
- bson_iter_t rp_iter ;
753
- bson_iter_t sd_iter ;
754
- uint32_t rp_len ;
755
- uint32_t sd_len ;
756
- const char * rp_val ;
757
- const char * sd_val ;
755
+ bson_iter_t tag_set_iter ;
758
756
bool * sd_matched = NULL ;
759
- size_t found ;
757
+ bool found ;
760
758
size_t i ;
761
759
762
760
if (!read_prefs ) {
@@ -777,7 +775,7 @@ mongoc_server_description_filter_tags (mongoc_server_description_t **description
777
775
778
776
/* for each read preference tag set */
779
777
while (bson_iter_next (& rp_tagset_iter )) {
780
- found = description_len ;
778
+ found = false ;
781
779
782
780
for (i = 0 ; i < description_len ; i ++ ) {
783
781
if (!descriptions [i ]) {
@@ -786,29 +784,10 @@ mongoc_server_description_filter_tags (mongoc_server_description_t **description
786
784
continue ;
787
785
}
788
786
789
- sd_matched [i ] = true;
790
-
791
- bson_iter_recurse (& rp_tagset_iter , & rp_iter );
792
-
793
- while (bson_iter_next (& rp_iter )) {
794
- rp_val = bson_iter_utf8 (& rp_iter , & rp_len );
795
-
796
- if (bson_iter_init_find (& sd_iter , & descriptions [i ]-> tags , bson_iter_key (& rp_iter ))) {
797
-
798
- /* If the server description has that key */
799
- sd_val = bson_iter_utf8 (& sd_iter , & sd_len );
800
-
801
- if (! (sd_len == rp_len && (0 == memcmp (rp_val , sd_val , rp_len )))) {
802
- /* If the key value doesn't match, no match */
803
- sd_matched [i ] = false;
804
- found -- ;
805
- }
806
- } else {
807
- /* If the server description doesn't have that key, no match */
808
- sd_matched [i ] = false;
809
- found -- ;
810
- break ;
811
- }
787
+ bson_iter_recurse (& rp_tagset_iter , & tag_set_iter );
788
+ sd_matched [i ] = _match_tag_set (descriptions [i ], & tag_set_iter );
789
+ if (sd_matched [i ]) {
790
+ found = true;
812
791
}
813
792
}
814
793
@@ -823,6 +802,7 @@ mongoc_server_description_filter_tags (mongoc_server_description_t **description
823
802
}
824
803
}
825
804
805
+ /* tried each */
826
806
for (i = 0 ; i < description_len ; i ++ ) {
827
807
if (! sd_matched [i ]) {
828
808
descriptions [i ] = NULL ;
@@ -832,3 +812,46 @@ mongoc_server_description_filter_tags (mongoc_server_description_t **description
832
812
CLEANUP :
833
813
bson_free (sd_matched );
834
814
}
815
+
816
+
817
+ /*
818
+ *-------------------------------------------------------------------------
819
+ *
820
+ * _match_tag_set --
821
+ *
822
+ * Check if a server's tags match one tag set, like
823
+ * {'tag1': 'value1', 'tag2': 'value2'}.
824
+ *
825
+ *-------------------------------------------------------------------------
826
+ */
827
+ static bool _match_tag_set (const mongoc_server_description_t * sd ,
828
+ bson_iter_t * tag_set_iter )
829
+ {
830
+ bson_iter_t sd_iter ;
831
+ uint32_t read_pref_tag_len ;
832
+ uint32_t sd_len ;
833
+ const char * read_pref_tag ;
834
+ const char * read_pref_val ;
835
+ const char * server_val ;
836
+
837
+ while (bson_iter_next (tag_set_iter )) {
838
+ /* one {'tag': 'value'} pair from the read preference's tag set */
839
+ read_pref_tag = bson_iter_key (tag_set_iter );
840
+ read_pref_val = bson_iter_utf8 (tag_set_iter , & read_pref_tag_len );
841
+
842
+ if (bson_iter_init_find (& sd_iter , & sd -> tags , read_pref_tag )) {
843
+ /* The server has this tag - does it have the right value? */
844
+ server_val = bson_iter_utf8 (& sd_iter , & sd_len );
845
+ if (sd_len != read_pref_tag_len ||
846
+ memcmp (read_pref_val , server_val , read_pref_tag_len )) {
847
+ /* If the values don't match, no match */
848
+ return false;
849
+ }
850
+ } else {
851
+ /* If the server description doesn't have that key, no match */
852
+ return false;
853
+ }
854
+ }
855
+
856
+ return true;
857
+ }
0 commit comments