diff --git a/frameworks/moveos-stdlib/doc/sort.md b/frameworks/moveos-stdlib/doc/sort.md index d22961be29..672b064675 100644 --- a/frameworks/moveos-stdlib/doc/sort.md +++ b/frameworks/moveos-stdlib/doc/sort.md @@ -24,7 +24,7 @@ Utility functions for sorting vector. Sorts a vector using quick sort algorithm. -
public fun quick_sort<T: copy, drop>(data: &mut vector<T>)
+public fun quick_sort<T>(data: &mut vector<T>)
@@ -37,7 +37,7 @@ Sorts a vector, returning a new vector with the sorted elements.
The sort algorithm used is quick sort, it maybe changed in the future.
-public fun sort<T: copy, drop>(data: &mut vector<T>)
+public fun sort<T>(data: &mut vector<T>)
@@ -50,7 +50,7 @@ Sorts a vector using a custom comparison function.
The comparison function should return true if the first element is greater than the second.
-public fun sort_by_cmp<T: copy, drop>(data: &mut vector<T>, cmp: |(&T, &T)|bool)
+public fun sort_by_cmp<T>(data: &mut vector<T>, cmp: |(&T, &T)|bool)
@@ -62,5 +62,5 @@ The comparison function should return true if the first element is greater than
Sorts a vector using a custom key function.
-public fun sort_by_key<T: copy, drop, K: copy, drop>(data: &mut vector<T>, key: |&T|K)
+public fun sort_by_key<T, K>(data: &mut vector<T>, key: |&T|&K)
diff --git a/frameworks/moveos-stdlib/sources/sort.move b/frameworks/moveos-stdlib/sources/sort.move
index e2e0b3fe8d..353bfd561e 100644
--- a/frameworks/moveos-stdlib/sources/sort.move
+++ b/frameworks/moveos-stdlib/sources/sort.move
@@ -5,7 +5,7 @@ module moveos_std::sort {
use moveos_std::compare;
/// Sorts a vector using quick sort algorithm.
- public fun quick_sort(data: &mut vector){
+ public fun quick_sort(data: &mut vector){
let len = vector::length(data);
if (len <= 1) {
return
@@ -13,7 +13,7 @@ module moveos_std::sort {
quick_sort_helper(data, 0, len - 1);
}
- fun quick_sort_helper(data: &mut vector, low: u64, high: u64) {
+ fun quick_sort_helper(data: &mut vector, low: u64, high: u64) {
if (low < high) {
let p = partition(data, low, high);
if (p > 0) {
@@ -23,13 +23,15 @@ module moveos_std::sort {
}
}
- fun partition(data: &mut vector, low: u64, high: u64): u64 {
- let pivot = *vector::borrow(data, high);
+ fun partition(data: &mut vector, low: u64, high: u64): u64 {
let i = low;
let j = low;
while (j < high) {
+ //for avoid pivot reference still alive when vector::swap
+ //we need to borrow it in the while loop, not before the loop
+ let pivot = vector::borrow(data, high);
let value = vector::borrow(data, j);
- let cmp = compare::compare(value, &pivot);
+ let cmp = compare::compare(value, pivot);
if (cmp == compare::result_less_than()) {
vector::swap(data, i, j);
i = i + 1;
@@ -40,7 +42,7 @@ module moveos_std::sort {
i
}
- inline fun bubble_sort(data: &mut vector, cmp: |&T, &T|bool) {
+ inline fun bubble_sort(data: &mut vector, cmp: |&T, &T|bool) {
let len = vector::length(data);
let swapped = true;
while(swapped) {
@@ -62,59 +64,23 @@ module moveos_std::sort {
/// Sorts a vector, returning a new vector with the sorted elements.
/// The sort algorithm used is quick sort, it maybe changed in the future.
- public fun sort(data: &mut vector){
+ public fun sort(data: &mut vector){
quick_sort(data)
}
/// Sorts a vector using a custom comparison function.
/// The comparison function should return true if the first element is greater than the second.
- public inline fun sort_by_cmp(data: &mut vector, cmp: |&T, &T|bool){
+ public inline fun sort_by_cmp(data: &mut vector, cmp: |&T, &T|bool){
bubble_sort(data, |a,b|{cmp(a,b)});
}
/// Sorts a vector using a custom key function.
- public inline fun sort_by_key(data: &mut vector, key: |&T|K){
+ public inline fun sort_by_key(data: &mut vector, key: |&T|&K){
bubble_sort(data, |a,b|{
let a_key = key(a);
let b_key = key(b);
- compare::compare(&a_key, &b_key) == compare::result_greater_than()
+ compare::compare(a_key, b_key) == compare::result_greater_than()
});
}
- #[test]
- fun test_quick_sort() {
- let data = vector[1, 3, 2, 5, 4];
- quick_sort(&mut data);
- assert!(vector::length(&data) == 5, 0);
- assert!(*vector::borrow(&data, 0) == 1, 0);
- assert!(*vector::borrow(&data, 1) == 2, 0);
- assert!(*vector::borrow(&data, 2) == 3, 0);
- assert!(*vector::borrow(&data, 3) == 4, 0);
- assert!(*vector::borrow(&data, 4) == 5, 0);
- }
-
- #[test]
- fun test_quick_sort_u128() {
- let data = vector[1, 3, 2, 5, 4];
- quick_sort(&mut data);
- assert!(vector::length(&data) == 5, 0);
- assert!(*vector::borrow(&data, 0) == 1, 0);
- assert!(*vector::borrow(&data, 1) == 2, 0);
- assert!(*vector::borrow(&data, 2) == 3, 0);
- assert!(*vector::borrow(&data, 3) == 4, 0);
- assert!(*vector::borrow(&data, 4) == 5, 0);
- }
-
- #[test]
- fun test_sort_by_cmp(){
- let data = vector[1, 3, 2, 5, 4, 1];
- sort_by_cmp(&mut data, |a,b|{*a > *b});
- assert!(vector::length(&data) == 6, 0);
- assert!(*vector::borrow(&data, 0) == 1, 0);
- assert!(*vector::borrow(&data, 1) == 1, 0);
- assert!(*vector::borrow(&data, 2) == 2, 0);
- assert!(*vector::borrow(&data, 3) == 3, 0);
- assert!(*vector::borrow(&data, 4) == 4, 0);
- assert!(*vector::borrow(&data, 5) == 5, 0);
- }
}
\ No newline at end of file
diff --git a/frameworks/moveos-stdlib/tests/sort_tests.move b/frameworks/moveos-stdlib/tests/sort_tests.move
index 2d39ea98a4..4498d3fa8d 100644
--- a/frameworks/moveos-stdlib/tests/sort_tests.move
+++ b/frameworks/moveos-stdlib/tests/sort_tests.move
@@ -8,12 +8,49 @@ module moveos_std::sort_tests {
use moveos_std::sort;
#[test_only]
- struct TestStruct has copy, drop{
+ struct TestStruct has drop{
value: u64
}
#[test]
- fun test_sort_by_cmp(){
+ fun test_quick_sort() {
+ let data = vector[1, 3, 2, 5, 4];
+ sort::quick_sort(&mut data);
+ assert!(vector::length(&data) == 5, 0);
+ assert!(*vector::borrow(&data, 0) == 1, 0);
+ assert!(*vector::borrow(&data, 1) == 2, 0);
+ assert!(*vector::borrow(&data, 2) == 3, 0);
+ assert!(*vector::borrow(&data, 3) == 4, 0);
+ assert!(*vector::borrow(&data, 4) == 5, 0);
+ }
+
+ #[test]
+ fun test_quick_sort_u128() {
+ let data = vector[1, 3, 2, 5, 4];
+ sort::quick_sort(&mut data);
+ assert!(vector::length(&data) == 5, 0);
+ assert!(*vector::borrow(&data, 0) == 1, 0);
+ assert!(*vector::borrow(&data, 1) == 2, 0);
+ assert!(*vector::borrow(&data, 2) == 3, 0);
+ assert!(*vector::borrow(&data, 3) == 4, 0);
+ assert!(*vector::borrow(&data, 4) == 5, 0);
+ }
+
+ #[test]
+ fun test_sort_by_cmp_u64(){
+ let data = vector[1, 3, 2, 5, 4, 1];
+ sort::sort_by_cmp(&mut data, |a,b|{*a > *b});
+ assert!(vector::length(&data) == 6, 0);
+ assert!(*vector::borrow(&data, 0) == 1, 0);
+ assert!(*vector::borrow(&data, 1) == 1, 0);
+ assert!(*vector::borrow(&data, 2) == 2, 0);
+ assert!(*vector::borrow(&data, 3) == 3, 0);
+ assert!(*vector::borrow(&data, 4) == 4, 0);
+ assert!(*vector::borrow(&data, 5) == 5, 0);
+ }
+
+ #[test]
+ fun test_sort_by_cmp_struct(){
let data = vector[
TestStruct{value: 1},
TestStruct{value: 3},
@@ -49,7 +86,7 @@ module moveos_std::sort_tests {
];
sort::sort_by_key(&mut data, |a|{
let a: &TestStruct = a;
- a.value
+ &a.value
}
);
assert!(vector::length(&data) == 6, 0);