@@ -7,9 +7,8 @@ use itertools::Itertools;
7
7
8
8
use super :: table:: InMemoryTableInnerRef ;
9
9
use super :: { InMemoryRowHandler , InMemoryTable , InMemoryTxnIterator } ;
10
- use crate :: array:: { ArrayBuilderImpl , ArrayImplBuilderPickExt , ArrayImplSortExt , DataChunk } ;
11
- use crate :: catalog:: { find_sort_key_id, ColumnCatalog } ;
12
- use crate :: storage:: { ScanOptions , StorageColumnRef , StorageResult , Transaction } ;
10
+ use crate :: array:: { ArrayBuilderImpl , ArrayImplBuilderPickExt , DataChunk } ;
11
+ use crate :: storage:: { ScanOptions , StorageColumnRef , StorageResult , Table , Transaction } ;
13
12
14
13
/// A transaction running on `InMemoryStorage`.
15
14
pub struct InMemoryTransaction {
@@ -34,31 +33,42 @@ pub struct InMemoryTransaction {
34
33
/// Snapshot of all deleted rows
35
34
deleted_rows : Arc < HashSet < usize > > ,
36
35
37
- /// All information about columns
38
- column_infos : Arc < [ ColumnCatalog ] > ,
36
+ /// Ordered primary key indexes in `column_infos`
37
+ ordered_pk_idx : Vec < usize > ,
39
38
}
40
39
41
40
impl InMemoryTransaction {
42
41
pub ( super ) fn start ( table : & InMemoryTable ) -> StorageResult < Self > {
43
42
let inner = table. inner . read ( ) . unwrap ( ) ;
43
+ let ordered_pk_idx = table
44
+ . ordered_pk_ids ( )
45
+ . iter ( )
46
+ . map ( |id| {
47
+ table
48
+ . columns
49
+ . iter ( )
50
+ . position ( |c| c. id ( ) == * id)
51
+ . expect ( "Malformed table object" )
52
+ } )
53
+ . collect_vec ( ) ;
44
54
Ok ( Self {
45
55
finished : false ,
46
56
buffer : vec ! [ ] ,
47
57
delete_buffer : vec ! [ ] ,
48
58
table : table. inner . clone ( ) ,
49
59
snapshot : Arc :: new ( inner. get_all_chunks ( ) ) ,
50
60
deleted_rows : Arc :: new ( inner. get_all_deleted_rows ( ) ) ,
51
- column_infos : table . columns . clone ( ) ,
61
+ ordered_pk_idx ,
52
62
} )
53
63
}
54
64
}
55
65
56
66
/// If primary key is found in [`ColumnCatalog`], sort all in-memory data using that key.
57
67
fn sort_datachunk_by_pk (
58
68
chunks : & Arc < Vec < DataChunk > > ,
59
- column_infos : & [ ColumnCatalog ] ,
69
+ ordered_pk_idx : & [ usize ] ,
60
70
) -> Arc < Vec < DataChunk > > {
61
- if let Some ( sort_key_id ) = find_sort_key_id ( column_infos ) {
71
+ if !ordered_pk_idx . is_empty ( ) {
62
72
if chunks. is_empty ( ) {
63
73
return chunks. clone ( ) ;
64
74
}
@@ -78,7 +88,15 @@ fn sort_datachunk_by_pk(
78
88
. into_iter ( )
79
89
. map ( |builder| builder. finish ( ) )
80
90
. collect_vec ( ) ;
81
- let sorted_index = arrays[ sort_key_id] . get_sorted_indices ( ) ;
91
+
92
+ let pk_arrays = Vec :: from ( ordered_pk_idx)
93
+ . iter ( )
94
+ . map ( |idx| & arrays[ * idx] )
95
+ . collect_vec ( ) ;
96
+ let pk_array = itertools:: izip!( pk_arrays) . collect_vec ( ) ;
97
+ let sorted_index = ( 0 ..pk_array. len ( ) )
98
+ . sorted_by_key ( |idx| pk_array[ * idx] )
99
+ . collect_vec ( ) ;
82
100
83
101
let chunk = arrays
84
102
. into_iter ( )
@@ -109,7 +127,7 @@ impl Transaction for InMemoryTransaction {
109
127
assert ! ( !opts. reversed, "reverse iterator is not supported for now" ) ;
110
128
111
129
let snapshot = if opts. is_sorted {
112
- sort_datachunk_by_pk ( & self . snapshot , & self . column_infos )
130
+ sort_datachunk_by_pk ( & self . snapshot , & self . ordered_pk_idx )
113
131
} else {
114
132
self . snapshot . clone ( )
115
133
} ;
0 commit comments