Skip to content
Snippets Groups Projects
Unverified Commit 6760a6e7 authored by broccoliSpicy's avatar broccoliSpicy Committed by GitHub
Browse files

Add decimal sort and decimal compare2 (#2503)

parent 7f5fc9f3
No related branches found
No related tags found
No related merge requests found
Showing
with 860 additions and 0 deletions
......@@ -39,6 +39,7 @@ func (c *compare) Set(idx int, v *vector.Vector) {
c.xs[idx] = v.Col.([]types.Decimal128)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return int(types.CompareDecimal128Decimal128(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
......
......@@ -39,6 +39,7 @@ func (c *compare) Set(idx int, v *vector.Vector) {
c.xs[idx] = v.Col.([]types.Decimal64)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return int(types.CompareDecimal64Decimal64(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
......
......@@ -17,6 +17,8 @@ package compare
import (
adates "github.com/matrixorigin/matrixone/pkg/compare/asc/dates"
adatetimes "github.com/matrixorigin/matrixone/pkg/compare/asc/datetimes"
adecimal128s "github.com/matrixorigin/matrixone/pkg/compare/asc/decimal128s"
adecimal64s "github.com/matrixorigin/matrixone/pkg/compare/asc/decimal64s"
afloat32s "github.com/matrixorigin/matrixone/pkg/compare/asc/float32s"
afloat64s "github.com/matrixorigin/matrixone/pkg/compare/asc/float64s"
aint16s "github.com/matrixorigin/matrixone/pkg/compare/asc/int16s"
......@@ -30,6 +32,8 @@ import (
avarchar "github.com/matrixorigin/matrixone/pkg/compare/asc/varchar"
ddates "github.com/matrixorigin/matrixone/pkg/compare/desc/dates"
ddatetimes "github.com/matrixorigin/matrixone/pkg/compare/desc/datetimes"
ddecimal128s "github.com/matrixorigin/matrixone/pkg/compare/desc/decimal128s"
ddecimal64s "github.com/matrixorigin/matrixone/pkg/compare/desc/decimal64s"
dfloat32s "github.com/matrixorigin/matrixone/pkg/compare/desc/float32s"
dfloat64s "github.com/matrixorigin/matrixone/pkg/compare/desc/float64s"
dint16s "github.com/matrixorigin/matrixone/pkg/compare/desc/int16s"
......@@ -111,6 +115,16 @@ func New(typ types.T, desc bool) Compare {
return ddatetimes.New()
}
return adatetimes.New()
case types.T_decimal64:
if desc {
return ddecimal64s.New()
}
return adecimal64s.New()
case types.T_decimal128:
if desc {
return ddecimal128s.New()
}
return adecimal128s.New()
}
return nil
}
......@@ -25,6 +25,7 @@ func (c *compare) Set(idx int, v *vector.Vector) {
c.xs[idx] = v.Col.([]types.Decimal128)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return -int(types.CompareDecimal128Decimal128(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
......
......@@ -25,6 +25,7 @@ func (c *compare) Set(idx int, v *vector.Vector) {
c.xs[idx] = v.Col.([]types.Decimal64)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return -int(types.CompareDecimal64Decimal64(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
......
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal128s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
process "github.com/matrixorigin/matrixone/pkg/vm/process2"
)
func New() *compare {
return &compare{
xs: make([][]types.Decimal128, 2),
ns: make([]*nulls.Nulls, 2),
vs: make([]*vector.Vector, 2),
}
}
func (c *compare) Vector() *vector.Vector {
return c.vs[0]
}
func (c *compare) Set(idx int, v *vector.Vector) {
c.vs[idx] = v
c.ns[idx] = v.Nsp
c.xs[idx] = v.Col.([]types.Decimal128)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return int(types.CompareDecimal128Decimal128(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
func (c *compare) Copy(vecSrc, vecDst int, src, dst int64, _ *process.Process) error {
if nulls.Any(c.ns[vecSrc]) && nulls.Contains(c.ns[vecSrc], (uint64(src))) {
nulls.Add(c.ns[vecDst], (uint64(dst)))
} else {
nulls.Del(c.ns[vecDst], (uint64(dst)))
c.xs[vecDst][dst] = c.xs[vecSrc][src]
}
return nil
}
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal128s
import (
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/stretchr/testify/require"
"testing"
)
func TestCompare_Compare(t *testing.T) {
c := New()
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 5})
c.xs[0] = make([]types.Decimal128, 2)
decimal128Value0, _ := types.ParseStringToDecimal128("12345.6789", 38, 5)
c.xs[0][0] = decimal128Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 5})
c.xs[1] = make([]types.Decimal128, 2)
decimal128Value1, _ := types.ParseStringToDecimal128("54321.54321", 38, 5)
c.xs[1][0] = decimal128Value1
result := c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal128Value0, _ = types.ParseStringToDecimal128("123.4", 38, 5)
c.xs[0][0] = decimal128Value0
decimal128Value1, _ = types.ParseStringToDecimal128("54.21", 38, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal128Value0, _ = types.ParseStringToDecimal128("123.4", 38, 5)
c.xs[0][0] = decimal128Value0
decimal128Value1, _ = types.ParseStringToDecimal128("123.4", 38, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 8})
c.xs[0] = make([]types.Decimal128, 2)
decimal128Value0, _ = types.ParseStringToDecimal128("12345.6789", 38, 8)
c.xs[0][0] = decimal128Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 5})
c.xs[1] = make([]types.Decimal128, 2)
decimal128Value1, _ = types.ParseStringToDecimal128("54321.54321", 38, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal128Value1, _ = types.ParseStringToDecimal128("5432.54", 18, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal128Value1, _ = types.ParseStringToDecimal128("12345.67890", 18, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
}
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal128s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
)
type compare struct {
xs [][]types.Decimal128
ns []*nulls.Nulls
vs []*vector.Vector
}
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal64s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
process "github.com/matrixorigin/matrixone/pkg/vm/process2"
)
func New() *compare {
return &compare{
xs: make([][]types.Decimal64, 2),
ns: make([]*nulls.Nulls, 2),
vs: make([]*vector.Vector, 2),
}
}
func (c *compare) Vector() *vector.Vector {
return c.vs[0]
}
func (c *compare) Set(idx int, v *vector.Vector) {
c.vs[idx] = v
c.ns[idx] = v.Nsp
c.xs[idx] = v.Col.([]types.Decimal64)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return int(types.CompareDecimal64Decimal64(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
func (c *compare) Copy(vecSrc, vecDst int, src, dst int64, _ *process.Process) error {
if nulls.Any(c.ns[vecSrc]) && nulls.Contains(c.ns[vecSrc], (uint64(src))) {
nulls.Add(c.ns[vecDst], (uint64(dst)))
} else {
nulls.Del(c.ns[vecDst], (uint64(dst)))
c.xs[vecDst][dst] = c.xs[vecSrc][src]
}
return nil
}
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal64s
import (
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/stretchr/testify/require"
"testing"
)
func TestCompare_Compare(t *testing.T) {
c := New()
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 5})
c.xs[0] = make([]types.Decimal64, 2)
decimal64Value0, _ := types.ParseStringToDecimal64("12345.6789", 18, 5)
c.xs[0][0] = decimal64Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 5})
c.xs[1] = make([]types.Decimal64, 2)
decimal64Value1, _ := types.ParseStringToDecimal64("54321.54321", 18, 5)
c.xs[1][0] = decimal64Value1
result := c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal64Value0, _ = types.ParseStringToDecimal64("123.4", 18, 5)
c.xs[0][0] = decimal64Value0
decimal64Value1, _ = types.ParseStringToDecimal64("54.21", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal64Value0, _ = types.ParseStringToDecimal64("123.4", 18, 5)
c.xs[0][0] = decimal64Value0
decimal64Value1, _ = types.ParseStringToDecimal64("123.4", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 8})
c.xs[0] = make([]types.Decimal64, 2)
decimal64Value0, _ = types.ParseStringToDecimal64("12345.6789", 18, 8)
c.xs[0][0] = decimal64Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 5})
c.xs[1] = make([]types.Decimal64, 2)
decimal64Value1, _ = types.ParseStringToDecimal64("54321.54321", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal64Value1, _ = types.ParseStringToDecimal64("5432.54", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal64Value1, _ = types.ParseStringToDecimal64("12345.67890", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
}
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal64s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
)
type compare struct {
xs [][]types.Decimal64
ns []*nulls.Nulls
vs []*vector.Vector
}
......@@ -17,6 +17,8 @@ package compare
import (
adates "github.com/matrixorigin/matrixone/pkg/compare2/asc/dates"
adatetimes "github.com/matrixorigin/matrixone/pkg/compare2/asc/datetimes"
adecimal128s "github.com/matrixorigin/matrixone/pkg/compare2/asc/decimal128s"
adecimal64s "github.com/matrixorigin/matrixone/pkg/compare2/asc/decimal64s"
afloat32s "github.com/matrixorigin/matrixone/pkg/compare2/asc/float32s"
afloat64s "github.com/matrixorigin/matrixone/pkg/compare2/asc/float64s"
aint16s "github.com/matrixorigin/matrixone/pkg/compare2/asc/int16s"
......@@ -30,6 +32,8 @@ import (
avarchar "github.com/matrixorigin/matrixone/pkg/compare2/asc/varchar"
ddates "github.com/matrixorigin/matrixone/pkg/compare2/desc/dates"
ddatetimes "github.com/matrixorigin/matrixone/pkg/compare2/desc/datetimes"
ddecimal128s "github.com/matrixorigin/matrixone/pkg/compare2/desc/decimal128s"
ddecimal64s "github.com/matrixorigin/matrixone/pkg/compare2/desc/decimal64s"
dfloat32s "github.com/matrixorigin/matrixone/pkg/compare2/desc/float32s"
dfloat64s "github.com/matrixorigin/matrixone/pkg/compare2/desc/float64s"
dint16s "github.com/matrixorigin/matrixone/pkg/compare2/desc/int16s"
......@@ -111,6 +115,16 @@ func New(typ types.T, desc bool) Compare {
return ddatetimes.New()
}
return adatetimes.New()
case types.T_decimal64:
if desc {
return ddecimal64s.New()
}
return adecimal64s.New()
case types.T_decimal128:
if desc {
return ddecimal128s.New()
}
return adecimal128s.New()
}
return nil
}
package decimal128s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
process "github.com/matrixorigin/matrixone/pkg/vm/process2"
)
func New() *compare {
return &compare{
xs: make([][]types.Decimal128, 2),
ns: make([]*nulls.Nulls, 2),
vs: make([]*vector.Vector, 2),
}
}
func (c *compare) Vector() *vector.Vector {
return c.vs[0]
}
func (c *compare) Set(idx int, v *vector.Vector) {
c.vs[idx] = v
c.ns[idx] = v.Nsp
c.xs[idx] = v.Col.([]types.Decimal128)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return -int(types.CompareDecimal128Decimal128(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
func (c *compare) Copy(vecSrc, vecDst int, src, dst int64, _ *process.Process) error {
if nulls.Any(c.ns[vecSrc]) && nulls.Contains(c.ns[vecSrc], (uint64(src))) {
nulls.Add(c.ns[vecDst], (uint64(dst)))
} else {
nulls.Del(c.ns[vecDst], (uint64(dst)))
c.xs[vecDst][dst] = c.xs[vecSrc][src]
}
return nil
}
package decimal128s
import (
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/stretchr/testify/require"
"testing"
)
func TestCompare_Compare(t *testing.T) {
c := New()
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 5})
c.xs[0] = make([]types.Decimal128, 2)
decimal128Value0, _ := types.ParseStringToDecimal128("12345.6789", 38, 5)
c.xs[0][0] = decimal128Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 5})
c.xs[1] = make([]types.Decimal128, 2)
decimal128Value1, _ := types.ParseStringToDecimal128("54321.54321", 38, 5)
c.xs[1][0] = decimal128Value1
result := c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal128Value0, _ = types.ParseStringToDecimal128("123.4", 38, 5)
c.xs[0][0] = decimal128Value0
decimal128Value1, _ = types.ParseStringToDecimal128("54.21", 38, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal128Value0, _ = types.ParseStringToDecimal128("123.4", 38, 5)
c.xs[0][0] = decimal128Value0
decimal128Value1, _ = types.ParseStringToDecimal128("123.4", 38, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 8})
c.xs[0] = make([]types.Decimal128, 2)
decimal128Value0, _ = types.ParseStringToDecimal128("12345.6789", 38, 8)
c.xs[0][0] = decimal128Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal128, Scale: 5})
c.xs[1] = make([]types.Decimal128, 2)
decimal128Value1, _ = types.ParseStringToDecimal128("54321.54321", 38, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal128Value1, _ = types.ParseStringToDecimal128("5432.54", 18, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal128Value1, _ = types.ParseStringToDecimal128("12345.67890", 18, 5)
c.xs[1][0] = decimal128Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
}
package decimal128s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
)
type compare struct {
xs [][]types.Decimal128
ns []*nulls.Nulls
vs []*vector.Vector
}
package decimal64s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
process "github.com/matrixorigin/matrixone/pkg/vm/process2"
)
func New() *compare {
return &compare{
xs: make([][]types.Decimal64, 2),
ns: make([]*nulls.Nulls, 2),
vs: make([]*vector.Vector, 2),
}
}
func (c *compare) Vector() *vector.Vector {
return c.vs[0]
}
func (c *compare) Set(idx int, v *vector.Vector) {
c.vs[idx] = v
c.ns[idx] = v.Nsp
c.xs[idx] = v.Col.([]types.Decimal64)
}
// Compare method for decimal needs to know the decimal's scale, so we need to fill in the c.vs field before using this function
func (c *compare) Compare(veci, vecj int, vi, vj int64) int {
return -int(types.CompareDecimal64Decimal64(c.xs[veci][vi], c.xs[vecj][vj], c.vs[0].Typ.Scale, c.vs[1].Typ.Scale))
}
func (c *compare) Copy(vecSrc, vecDst int, src, dst int64, _ *process.Process) error {
if nulls.Any(c.ns[vecSrc]) && nulls.Contains(c.ns[vecSrc], (uint64(src))) {
nulls.Add(c.ns[vecDst], (uint64(dst)))
} else {
nulls.Del(c.ns[vecDst], (uint64(dst)))
c.xs[vecDst][dst] = c.xs[vecSrc][src]
}
return nil
}
package decimal64s
import (
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/stretchr/testify/require"
"testing"
)
func TestCompare_Compare(t *testing.T) {
c := New()
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 5})
c.xs[0] = make([]types.Decimal64, 2)
decimal64Value0, _ := types.ParseStringToDecimal64("12345.6789", 18, 5)
c.xs[0][0] = decimal64Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 5})
c.xs[1] = make([]types.Decimal64, 2)
decimal64Value1, _ := types.ParseStringToDecimal64("54321.54321", 18, 5)
c.xs[1][0] = decimal64Value1
result := c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal64Value0, _ = types.ParseStringToDecimal64("123.4", 18, 5)
c.xs[0][0] = decimal64Value0
decimal64Value1, _ = types.ParseStringToDecimal64("54.21", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal64Value0, _ = types.ParseStringToDecimal64("123.4", 18, 5)
c.xs[0][0] = decimal64Value0
decimal64Value1, _ = types.ParseStringToDecimal64("123.4", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
c.vs[0] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 8})
c.xs[0] = make([]types.Decimal64, 2)
decimal64Value0, _ = types.ParseStringToDecimal64("12345.6789", 18, 8)
c.xs[0][0] = decimal64Value0
c.vs[1] = vector.New(types.Type{Oid: types.T_decimal64, Scale: 5})
c.xs[1] = make([]types.Decimal64, 2)
decimal64Value1, _ = types.ParseStringToDecimal64("54321.54321", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 1, result)
decimal64Value1, _ = types.ParseStringToDecimal64("5432.54", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, -1, result)
decimal64Value1, _ = types.ParseStringToDecimal64("12345.67890", 18, 5)
c.xs[1][0] = decimal64Value1
result = c.Compare(0, 1, 0, 0)
require.Equal(t, 0, result)
}
package decimal64s
import (
"github.com/matrixorigin/matrixone/pkg/container/nulls"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
)
type compare struct {
xs [][]types.Decimal64
ns []*nulls.Nulls
vs []*vector.Vector
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// modified by MatrixOrigin
// this implementation is inefficient due to too much cgo function call,
// to optimize this code, we may need to write these function directly in cgo.
package decimal128s
import "github.com/matrixorigin/matrixone/pkg/container/types"
// Sort sorts data.
// It makes one call to data.Len to determine n, and Operator(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(vs []types.Decimal128, os []int64) {
n := len(os)
quickSort(vs, os, 0, n, maxDepth(n))
}
// maxDepth returns a threshold at which quicksort should switch
// to heapsort. It returns 2*ceil(lg(n+1)).
func maxDepth(n int) int {
var depth int
for i := n; i > 0; i >>= 1 {
depth++
}
return depth * 2
}
func quickSort(vs []types.Decimal128, os []int64, a, b, maxDepth int) {
for b-a > 12 { // Use ShellSort for slices <= 12 elements
if maxDepth == 0 {
heapSort(vs, os, a, b)
return
}
maxDepth--
mlo, mhi := doPivot(vs, os, a, b)
// Avoiding recursion on the larger subproblem guarantees
// a stack depth of at most lg(b-a).
if mlo-a < b-mhi {
quickSort(vs, os, a, mlo, maxDepth)
a = mhi // i.e., quickSort(data, mhi, b)
} else {
quickSort(vs, os, mhi, b, maxDepth)
b = mlo // i.e., quickSort(data, a, mlo)
}
}
if b-a > 1 {
// Do ShellSort pass with gap 6
// It could be written in this simplified form cause b-a <= 12
for i := a + 6; i < b; i++ {
if types.CompareDecimal128Decimal128Aligned(vs[os[i]], vs[os[i-6]]) == -1 {
os[i], os[i-6] = os[i-6], os[i]
}
}
insertionSort(vs, os, a, b)
}
}
// Insertion sort
func insertionSort(vs []types.Decimal128, os []int64, a, b int) {
for i := a + 1; i < b; i++ {
for j := i; j > a && types.CompareDecimal128Decimal128Aligned(vs[os[j]], vs[os[j-1]]) == -1; j-- {
os[j], os[j-1] = os[j-1], os[j]
}
}
}
// siftDown implements the heap property on data[lo, hi).
// first is an offset into the array where the root of the heap lies.
func siftDown(vs []types.Decimal128, os []int64, lo, hi, first int) {
root := lo
for {
child := 2*root + 1
if child >= hi {
break
}
if child+1 < hi && types.CompareDecimal128Decimal128Aligned(vs[os[first+child]], vs[os[first+child+1]]) == -1 {
child++
}
if types.CompareDecimal128Decimal128Aligned(vs[os[first+root]], vs[os[first+child]]) >= 0 {
return
}
os[first+root], os[first+child] = os[first+child], os[first+root]
root = child
}
}
func heapSort(vs []types.Decimal128, os []int64, a, b int) {
first := a
lo := 0
hi := b - a
// Build heap with the greatest element at top.
for i := (hi - 1) / 2; i >= 0; i-- {
siftDown(vs, os, i, hi, first)
}
// Pop elements, largest first, into end of data.
for i := hi - 1; i >= 0; i-- {
os[first], os[first+i] = os[first+i], os[first]
siftDown(vs, os, lo, i, first)
}
}
// Quicksort, loosely following Bentley and McIlroy,
// ``Engineering a Sort Function,'' SP&E November 1993.
// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].
func medianOfThree(vs []types.Decimal128, os []int64, m1, m0, m2 int) {
// sort 3 elements
if types.CompareDecimal128Decimal128Aligned(vs[os[m1]], vs[os[m0]]) == -1 {
os[m1], os[m0] = os[m0], os[m1]
}
// data[m0] <= data[m1]
if types.CompareDecimal128Decimal128Aligned(vs[os[m2]], vs[os[m1]]) == -1 {
os[m2], os[m1] = os[m1], os[m2]
// data[m0] <= data[m2] && data[m1] < data[m2]
if types.CompareDecimal128Decimal128Aligned(vs[os[m1]], vs[os[m0]]) == -1 {
os[m1], os[m0] = os[m0], os[m1]
}
}
// now data[m0] <= data[m1] <= data[m2]
}
func swapRange(vs []types.Decimal128, os []int64, a, b, n int) {
for i := 0; i < n; i++ {
os[a+i], os[b+i] = os[b+i], os[a+i]
}
}
func doPivot(vs []types.Decimal128, os []int64, lo, hi int) (midlo, midhi int) {
m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.
if hi-lo > 40 {
// Tukey's ``Ninther,'' median of three medians of three.
s := (hi - lo) / 8
medianOfThree(vs, os, lo, lo+s, lo+2*s)
medianOfThree(vs, os, m, m-s, m+s)
medianOfThree(vs, os, hi-1, hi-1-s, hi-1-2*s)
}
medianOfThree(vs, os, lo, m, hi-1)
// Invariants are:
// data[lo] = pivot (set up by ChoosePivot)
// data[lo < i < a] < pivot
// data[a <= i < b] <= pivot
// data[b <= i < c] unexamined
// data[c <= i < hi-1] > pivot
// data[hi-1] >= pivot
pivot := lo
a, c := lo+1, hi-1
for ; a < c && types.CompareDecimal128Decimal128Aligned(vs[os[a]], vs[os[pivot]]) == -1; a++ {
}
b := a
for {
for ; b < c && types.CompareDecimal128Decimal128Aligned(vs[os[pivot]], vs[os[b]]) >= 0; b++ { // data[b] <= pivot
}
for ; b < c && types.CompareDecimal128Decimal128Aligned(vs[os[pivot]], vs[os[c-1]]) == -1; c-- { // data[c-1] > pivot
}
if b >= c {
break
}
// data[b] > pivot; data[c-1] <= pivot
os[b], os[c-1] = os[c-1], os[b]
b++
c--
}
// If hi-c<3 then there are duplicates (by property of median of nine).
// Let's be a bit more conservative, and set border to 5.
protect := hi-c < 5
if !protect && hi-c < (hi-lo)/4 {
// Lets test some points for equality to pivot
dups := 0
if types.CompareDecimal128Decimal128Aligned(vs[os[pivot]], vs[os[hi-1]]) >= 0 { // data[hi-1] = pivot
os[c], os[hi-1] = os[hi-1], os[c]
c++
dups++
}
if types.CompareDecimal128Decimal128Aligned(vs[os[b-1]], vs[os[pivot]]) >= 0 { // data[b-1] = pivot
b--
dups++
}
// m-lo = (hi-lo)/2 > 6
// b-lo > (hi-lo)*3/4-1 > 8
// ==> m < b ==> data[m] <= pivot
if types.CompareDecimal128Decimal128Aligned(vs[os[m]], vs[os[pivot]]) >= 0 { // data[m] = pivot
os[m], os[b-1] = os[b-1], os[m]
b--
dups++
}
// if at least 2 points are equal to pivot, assume skewed distribution
protect = dups > 1
}
if protect {
// Protect against a lot of duplicates
// Add invariant:
// data[a <= i < b] unexamined
// data[b <= i < c] = pivot
for {
for ; a < b && types.CompareDecimal128Decimal128Aligned(vs[os[b-1]], vs[os[pivot]]) >= 0; b-- { // data[b] == pivot
}
for ; a < b && types.CompareDecimal128Decimal128Aligned(vs[os[a]], vs[os[pivot]]) == -1; a++ { // data[a] < pivot
}
if a >= b {
break
}
// data[a] == pivot; data[b-1] < pivot
os[a], os[b-1] = os[b-1], os[a]
a++
b--
}
}
// Swap pivot into middle
os[pivot], os[b-1] = os[b-1], os[pivot]
return b - 1, c
}
// Copyright 2021 Matrix Origin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package decimal128s
import (
"fmt"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)
const Num = 10
func generate() ([]types.Decimal128, []int64) {
os := make([]int64, Num)
xs := make([]types.Decimal128, Num)
{
for i := 0; i < Num; i++ {
os[i] = int64(i)
}
xs[0], _ = types.ParseStringToDecimal128("12.34", 38, 3)
xs[1], _ = types.ParseStringToDecimal128("12.33", 38, 3)
xs[2], _ = types.ParseStringToDecimal128("-12.33", 38, 3)
xs[3], _ = types.ParseStringToDecimal128("0", 38, 3)
xs[4], _ = types.ParseStringToDecimal128("5", 38, 3)
xs[5], _ = types.ParseStringToDecimal128("12345.678", 38, 3)
xs[6], _ = types.ParseStringToDecimal128("12345.678", 38, 3)
xs[7], _ = types.ParseStringToDecimal128("123456.78", 38, 3)
xs[8], _ = types.ParseStringToDecimal128("-123456.78", 38, 3)
xs[9], _ = types.ParseStringToDecimal128("-123456.77", 38, 3)
}
return xs, os
}
func TestSort(t *testing.T) {
vs, os := generate()
for i := 1; i < len(os); i++ {
fmt.Println(string(vs[os[i]].Decimal128ToString(3)))
}
fmt.Println("decimal128 after sorting")
Sort(vs, os)
for i := 1; i < len(os); i++ {
fmt.Println(string(vs[os[i]].Decimal128ToString(3)))
}
}
func TestHeapSort(t *testing.T) {
vs, os := generate()
heapSort(vs, os, 0, len(vs))
for i := 1; i < len(os); i++ {
require.GreaterOrEqual(t, types.CompareDecimal128Decimal128Aligned(vs[os[i]], vs[os[i-1]]), int64(0))
}
}
func TestMedianOfThree(t *testing.T) {
vs, os := generate()
medianOfThree(vs, os, 0, 1, 2)
assert.True(t, (types.CompareDecimal128Decimal128Aligned(vs[os[0]], vs[os[1]]) >= 0 && types.CompareDecimal128Decimal128Aligned(vs[os[0]], vs[os[2]]) <= 0) || (types.CompareDecimal128Decimal128Aligned(vs[os[0]], vs[os[1]]) <= 0 && types.CompareDecimal128Decimal128Aligned(vs[os[0]], vs[os[2]]) >= 0))
medianOfThree(vs, os, 5, 6, 7)
assert.True(t, (types.CompareDecimal128Decimal128Aligned(vs[os[5]], vs[os[6]]) >= 0 && types.CompareDecimal128Decimal128Aligned(vs[os[5]], vs[os[7]]) <= 0) || (types.CompareDecimal128Decimal128Aligned(vs[os[5]], vs[os[6]]) <= 0 && types.CompareDecimal128Decimal128Aligned(vs[os[5]], vs[os[7]]) >= 0))
}
func TestSwapRange(t *testing.T) {
vs, os := generate()
osOriginal := make([]int64, len(os))
copy(osOriginal, os)
swapRange(vs, os, 0, 5, 5)
require.Equal(t, osOriginal[:5], os[5:10])
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment