Skip to content

Commit 3f767ce

Browse files
liyafan82emkornfield
authored andcommitted
ARROW-5719: [Java] Support in-place vector sorting
Support in-place sorting for vectors. An in-place sorter sorts the vector by directly modifying the vector data, so the input and output vectors are the same one. Author: liyafan82 <fan_li_ya@foxmail.com> Closes apache#4699 from liyafan82/fly_0625_isort and squashes the following commits: 2b4fc82 <liyafan82> Remove type width 1f210d9 <liyafan82> Remove data copier e3400a9 <liyafan82> Support in-place vector sorting
1 parent 90affbd commit 3f767ce

3 files changed

Lines changed: 206 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.arrow.algorithm.sort;
19+
20+
import org.apache.arrow.vector.BaseFixedWidthVector;
21+
22+
/**
23+
* Default in-place sorter for fixed-width vectors.
24+
* It is based on quick-sort, with average time complexity O(n*log(n)).
25+
* @param <V> vector type.
26+
*/
27+
public class FixedWidthInPlaceVectorSorter<V extends BaseFixedWidthVector> implements InPlaceVectorSorter<V> {
28+
29+
private VectorValueComparator<V> comparator;
30+
31+
/**
32+
* The vector to sort.
33+
*/
34+
private V vec;
35+
36+
/**
37+
* The buffer to hold the pivot.
38+
* It always has length 1.
39+
*/
40+
private V pivotBuffer;
41+
42+
@Override
43+
public void sortInPlace(V vec, VectorValueComparator<V> comparator) {
44+
try {
45+
this.vec = vec;
46+
this.comparator = comparator;
47+
this.pivotBuffer = (V) vec.getField().createVector(vec.getAllocator());
48+
this.pivotBuffer.allocateNew(1);
49+
50+
comparator.attachVectors(vec, pivotBuffer);
51+
quickSort(0, vec.getValueCount() - 1);
52+
} finally {
53+
this.pivotBuffer.close();
54+
}
55+
}
56+
57+
private void quickSort(int low, int high) {
58+
if (low < high) {
59+
int mid = partition(low, high);
60+
quickSort(low, mid - 1);
61+
quickSort(mid + 1, high);
62+
}
63+
}
64+
65+
private int partition(int low, int high) {
66+
pivotBuffer.copyFrom(low, 0, vec);
67+
68+
while (low < high) {
69+
while (low < high && comparator.compare(high, 0) >= 0) {
70+
high -= 1;
71+
}
72+
vec.copyFrom(high, low, vec);
73+
74+
while (low < high && comparator.compare(low, 0) <= 0) {
75+
low += 1;
76+
}
77+
vec.copyFrom(low, high, vec);
78+
}
79+
80+
vec.copyFrom(0, low, pivotBuffer);
81+
return low;
82+
}
83+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.arrow.algorithm.sort;
19+
20+
import org.apache.arrow.vector.ValueVector;
21+
22+
/**
23+
* Basic interface for sorting a vector in-place.
24+
* That is, the sorting is performed by modifying the input vector,
25+
* without creating a new sorted vector.
26+
*
27+
* @param <V> the vector type.
28+
*/
29+
public interface InPlaceVectorSorter<V extends ValueVector> {
30+
31+
/**
32+
* Sort a vector in-place.
33+
* @param vec the vector to sort.
34+
* @param comparator the criteria for sort.
35+
*/
36+
void sortInPlace(V vec, VectorValueComparator<V> comparator);
37+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.arrow.algorithm.sort;
19+
20+
import static org.junit.Assert.assertTrue;
21+
22+
import org.apache.arrow.memory.BufferAllocator;
23+
import org.apache.arrow.memory.RootAllocator;
24+
import org.apache.arrow.vector.IntVector;
25+
import org.junit.After;
26+
import org.junit.Assert;
27+
import org.junit.Before;
28+
import org.junit.Test;
29+
30+
/**
31+
* Test cases for {@link FixedWidthInPlaceVectorSorter}.
32+
*/
33+
public class TestFixedWidthInPlaceVectorSorter {
34+
35+
private BufferAllocator allocator;
36+
37+
@Before
38+
public void prepare() {
39+
allocator = new RootAllocator(1024 * 1024);
40+
}
41+
42+
@After
43+
public void shutdown() {
44+
allocator.close();
45+
}
46+
47+
@Test
48+
public void testSortInt() {
49+
try (IntVector vec = new IntVector("", allocator)) {
50+
vec.allocateNew(10);
51+
vec.setValueCount(10);
52+
53+
// fill data to sort
54+
vec.set(0, 10);
55+
vec.set(1, 8);
56+
vec.setNull(2);
57+
vec.set(3, 10);
58+
vec.set(4, 12);
59+
vec.set(5, 17);
60+
vec.setNull(6);
61+
vec.set(7, 23);
62+
vec.set(8, 35);
63+
vec.set(9, 2);
64+
65+
// sort the vector
66+
FixedWidthInPlaceVectorSorter sorter = new FixedWidthInPlaceVectorSorter();
67+
DefaultVectorComparators.IntComparator comparator = new DefaultVectorComparators.IntComparator();
68+
69+
sorter.sortInPlace(vec, comparator);
70+
71+
// verify results
72+
Assert.assertEquals(10, vec.getValueCount());
73+
74+
assertTrue(vec.isNull(0));
75+
assertTrue(vec.isNull(1));
76+
Assert.assertEquals(2, vec.get(2));
77+
Assert.assertEquals(8, vec.get(3));
78+
Assert.assertEquals(10, vec.get(4));
79+
Assert.assertEquals(10, vec.get(5));
80+
Assert.assertEquals(12, vec.get(6));
81+
Assert.assertEquals(17, vec.get(7));
82+
Assert.assertEquals(23, vec.get(8));
83+
Assert.assertEquals(35, vec.get(9));
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)