@@ -47,7 +47,6 @@ struct ListBucketResult {
4747 std::string StartAfter;
4848};
4949
50-
5150class S3Client {
5251public:
5352 // TODO(cristian): We should accept and define the endpoint url here
@@ -66,35 +65,42 @@ class S3Client {
6665 HttpRequest req = Client.get (std::format (" http://127.0.0.1:9000/{}?prefix={}&max-keys={}" , bucket, prefix, maxKeys)).header (" Host" , " 127.0.0.1" );
6766 Signer.sign (req);
6867 HttpResponse res = req.execute ();
69- ListBucketResult response;
70- response = deserializeListBucketResult (Parser.parse (res.body ()));
71- return response;
68+ ListBucketResult response = deserializeListBucketResult (Parser.parse (res.body ()), maxKeys);
69+ return response;
7270 }
7371
74- ListBucketResult deserializeListBucketResult (const std::vector<XMLNode>& nodes) {
72+ ListBucketResult deserializeListBucketResult (const std::vector<XMLNode>& nodes, const int maxKeys ) {
7573 // TODO(cristian): Detect and parse errors
7674 ListBucketResult response;
77- response.Contents .push_back (Contents_{});
75+ response.Contents .reserve (maxKeys);
76+ response.CommonPrefixes .reserve (maxKeys);
77+
78+ response.Contents .push_back (Contents_ {});
7879 response.CommonPrefixes .push_back (CommonPrefix {});
80+
7981 int contentsIdx = 0 ;
8082 int commonPrefixesIdx = 0 ;
8183
8284 // To keep track when we need to append an element
83- std::unordered_set <std::string> contentsKeySet ;
84- std::unordered_set <std::string> commonPrefixKeySet ;
85+ std::vector <std::string_view> seenContents ;
86+ std::vector <std::string_view> seenCommonPrefix ;
8587
8688 for (const auto & node : nodes) {
8789 /* Sigh... no reflection */
8890
8991 // Check if we've seen this tag before in the current object
90- if (contentsKeySet.contains (node.tag )) {
91- response.Contents .push_back (Contents_{});
92- contentsKeySet.clear ();
93- contentsIdx++;
94- } else if (commonPrefixKeySet.contains (node.tag )) {
95- response.CommonPrefixes .push_back (CommonPrefix {});
96- commonPrefixKeySet.clear ();
97- commonPrefixesIdx++;
92+ if (node.tag .contains (" ListBucketResult.Contents" )) {
93+ if (std::find (seenContents.begin (), seenContents.end (), node.tag ) != seenContents.end ()) {
94+ response.Contents .push_back (Contents_ {});
95+ seenContents.clear ();
96+ contentsIdx++;
97+ }
98+ } else if (node.tag .contains (" ListBucketResult.CommonPrefix" )) {
99+ if (std::find (seenCommonPrefix.begin (), seenCommonPrefix.end (), node.tag ) != seenCommonPrefix.end ()) {
100+ response.CommonPrefixes .push_back (CommonPrefix {});
101+ seenCommonPrefix.clear ();
102+ commonPrefixesIdx++;
103+ }
98104 }
99105
100106 if (node.tag == " ListBucketResult.IsTruncated" ) {
@@ -141,9 +147,9 @@ class S3Client {
141147
142148 // Add already seen fields
143149 if (node.tag .contains (" ListBucketResult.Contents" )) {
144- contentsKeySet. insert (node.tag );
150+ seenContents. push_back (node.tag );
145151 } else if (node.tag .contains (" ListBucketResult.CommonPrefix" )) {
146- commonPrefixKeySet. insert (node.tag );
152+ seenCommonPrefix. push_back (node.tag );
147153 }
148154 }
149155 return response;
0 commit comments