carlvinhust2012 commented on code in PR #11306:
URL: https://github.com/apache/doris/pull/11306#discussion_r936186571


##########
be/src/vec/functions/array/function_array_sort.cpp:
##########
@@ -15,12 +15,203 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include "vec/functions/array/function_array_sort.h"
-
+#include "vec/functions/array/function_array_unary.h"
 #include "vec/functions/simple_function_factory.h"
 
 namespace doris::vectorized {
 
+struct NameArraySort {
+    static constexpr auto name = "array_sort";
+};
+
+struct ArraySortImpl {
+    // sort the non-null element according to the permutation
+    template <typename SrcDataType>
+    static void _sort_by_permutation(ColumnArray::Offset& prev_offset,
+                                     const ColumnArray::Offset& curr_offset,
+                                     const SrcDataType* src_data_concrete,
+                                     const IColumn& src_column, const 
NullMapType* src_null_map,
+                                     IColumn::Permutation& permutation) {
+        for (ColumnArray::Offset j = prev_offset; j < curr_offset - 1; ++j) {
+            if (src_null_map && (*src_null_map)[j]) {
+                continue;
+            }
+            for (ColumnArray::Offset k = j + 1; k < curr_offset; ++k) {
+                if (src_null_map && (*src_null_map)[k]) {
+                    continue;
+                }
+                int result = src_data_concrete->compare_at(permutation[j], 
permutation[k],
+                                                           src_column, 1);
+                if (result > 0) {
+                    auto temp = permutation[j];
+                    permutation[j] = permutation[k];
+                    permutation[k] = temp;
+                }
+            }
+        }
+        return;
+    }
+
+    template <typename ColumnType>
+    static bool _execute_number(const IColumn& src_column, const 
ColumnArray::Offsets& src_offsets,
+                                IColumn& dest_column, ColumnArray::Offsets& 
dest_offsets,
+                                const NullMapType* src_null_map, NullMapType* 
dest_null_map) {
+        using NestType = typename ColumnType::value_type;
+        const ColumnType* src_data_concrete = reinterpret_cast<const 
ColumnType*>(&src_column);
+        if (!src_data_concrete) {
+            return false;
+        }
+        const PaddedPODArray<NestType>& src_datas = 
src_data_concrete->get_data();
+
+        ColumnType& dest_data_concrete = 
reinterpret_cast<ColumnType&>(dest_column);
+        PaddedPODArray<NestType>& dest_datas = dest_data_concrete.get_data();
+
+        ColumnArray::Offset prev_src_offset = 0;
+        IColumn::Permutation permutation(src_column.size());
+        for (size_t i = 0; i < src_column.size(); ++i) {
+            permutation[i] = i;
+        }
+
+        for (auto curr_src_offset : src_offsets) {
+            // filter and insert null element first
+            for (ColumnArray::Offset j = prev_src_offset; j < curr_src_offset; 
++j) {
+                if (src_null_map && (*src_null_map)[j]) {
+                    DCHECK(dest_null_map != nullptr);
+                    (*dest_null_map).push_back(true);
+                    dest_datas.push_back(NestType());
+                }
+            }
+
+            _sort_by_permutation<ColumnType>(prev_src_offset, curr_src_offset, 
src_data_concrete,
+                                             src_column, src_null_map, 
permutation);
+
+            // insert non-null element after sort by permutation
+            for (ColumnArray::Offset j = prev_src_offset; j < curr_src_offset; 
++j) {
+                if (src_null_map && (*src_null_map)[j]) {
+                    continue;
+                }
+
+                dest_datas.push_back(src_datas[permutation[j]]);
+                if (dest_null_map) {
+                    (*dest_null_map).push_back(false);
+                }
+            }
+            dest_offsets.push_back(curr_src_offset);
+            prev_src_offset = curr_src_offset;
+        }
+
+        return true;
+    }
+
+    static bool _execute_string(const IColumn& src_column, const 
ColumnArray::Offsets& src_offsets,
+                                IColumn& dest_column, ColumnArray::Offsets& 
dest_offsets,
+                                const NullMapType* src_null_map, NullMapType* 
dest_null_map) {
+        const ColumnString* src_data_concrete = reinterpret_cast<const 
ColumnString*>(&src_column);
+        if (!src_data_concrete) {
+            return false;
+        }
+
+        ColumnString& dest_column_string = 
reinterpret_cast<ColumnString&>(dest_column);
+        ColumnString::Chars& column_string_chars = 
dest_column_string.get_chars();
+        ColumnString::Offsets& column_string_offsets = 
dest_column_string.get_offsets();
+        column_string_chars.reserve(src_column.size());
+
+        ColumnArray::Offset prev_src_offset = 0;
+        IColumn::Permutation permutation(src_column.size());
+        for (size_t i = 0; i < src_column.size(); ++i) {
+            permutation[i] = i;
+        }
+
+        for (auto curr_src_offset : src_offsets) {
+            // filter and insert null element first
+            for (ColumnArray::Offset j = prev_src_offset; j < curr_src_offset; 
++j) {
+                if (src_null_map && (*src_null_map)[j]) {
+                    DCHECK(dest_null_map != nullptr);
+                    
column_string_offsets.push_back(column_string_offsets.back());
+                    (*dest_null_map).push_back(true);
+                }
+            }
+
+            _sort_by_permutation<ColumnString>(prev_src_offset, 
curr_src_offset, src_data_concrete,
+                                               src_column, src_null_map, 
permutation);
+
+            // insert non-null element after sort by permutation
+            for (ColumnArray::Offset j = prev_src_offset; j < curr_src_offset; 
++j) {
+                if (src_null_map && (*src_null_map)[j]) {
+                    continue;
+                }
+
+                StringRef src_str_ref = 
src_data_concrete->get_data_at(permutation[j]);
+                // copy the src data to column_string_chars
+                const size_t old_size = column_string_chars.size();
+                const size_t new_size = old_size + src_str_ref.size + 1;
+                column_string_chars.resize(new_size);
+                if (src_str_ref.size > 0) {
+                    memcpy(column_string_chars.data() + old_size, 
src_str_ref.data,
+                           src_str_ref.size);
+                }
+                column_string_chars[old_size + src_str_ref.size] = 0;
+                column_string_offsets.push_back(new_size);
+
+                if (dest_null_map) {
+                    (*dest_null_map).push_back(false);
+                }
+            }
+            dest_offsets.push_back(curr_src_offset);
+            prev_src_offset = curr_src_offset;
+        }
+        return true;
+    }
+
+    static bool _execute_by_type(const IColumn& src_column, const 
ColumnArray::Offsets& src_offsets,

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to