DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
RawTableInfo.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 
21 namespace Deveel.Data.Sql.Tables {
22  public sealed class RawTableInfo {
23  private readonly List<RawTableItem> tableItems;
24 
25  public RawTableInfo() {
26  tableItems = new List<RawTableItem>();
27  }
28 
29  private RawTableInfo(IEnumerable<RawTableItem> tableItems)
30  : this() {
31  this.tableItems.AddRange(tableItems);
32  }
33 
34  public void Add(IRootTable table, IList<int> rowSet) {
35  tableItems.Add(new RawTableItem(table, rowSet));
36  }
37 
38  public ITable[] GetTables() {
39  return tableItems.Select(x => x.Table).Cast<ITable>().ToArray();
40  }
41 
42  public IList<int>[] GetRows() {
43  return tableItems.Select(x => x.Rows).ToArray();
44  }
45 
47  var list = new RawTableItem[tableItems.Count];
48  tableItems.CopyTo(list);
49  Array.Sort(list);
50  return list;
51  }
52 
54  // Number of Table 'columns'
55 
56  int colCount = tableItems.Count;
57 
58  var merge1 = GetSortedItems();
59  var merge2 = info.GetSortedItems();
60 
61  int size1 = -1;
62  int size2 = -1;
63 
64  // First check number of tables in each merge is correct.
65 
66  if (merge1.Length != merge2.Length)
67  throw new InvalidOperationException("Incorrect format in table union");
68 
69  // Check each table in the merge1 set has identical length row_sets
70 
71  for (int i = 0; i < merge1.Length; ++i) {
72  if (size1 == -1) {
73  size1 = merge1[i].Rows.Count;
74  } else {
75  if (size1 != merge1[i].Rows.Count)
76  throw new InvalidOperationException("Incorrect format in table union");
77  }
78  }
79 
80  // Check each table in the merge2 set has identical length row_sets
81 
82  for (int i = 0; i < merge2.Length; ++i) {
83  // Check the tables in merge2 are identical to the tables in merge1
84  if (!merge2[i].Table.TypeEquals(merge1[i].Table))
85  throw new InvalidOperationException("Incorrect format in table union");
86 
87  if (size2 == -1) {
88  size2 = merge2[i].Rows.Count;
89  } else {
90  if (size2 != merge2[i].Rows.Count)
91  throw new InvalidOperationException("Incorrect format in table union");
92  }
93  }
94 
95  // If size1 or size2 are -1 then we have a corrupt table. (It will be
96  // 0 for an empty table).
97 
98  if (size1 == -1 || size2 == -1)
99  throw new InvalidOperationException("Incorrect format in table union");
100 
101  // We don't need information in 'raw_info' vector anymore so clear it.
102  // This may help garbage collection.
103 
104  var resultItems = new List<RawTableItem>();
105 
106  // Merge the two together into a new list of RawRowElement[]
107 
108  int mergeSize = size1 + size2;
109  var elems = new RawRowItem[mergeSize];
110  int elemsIndex = 0;
111 
112  for (int i = 0; i < size1; ++i) {
113  var itemRows = new int[colCount];
114 
115  for (int n = 0; n < colCount; ++n) {
116  itemRows[n] = merge1[n].Rows[i];
117  }
118 
119  elems[elemsIndex] = new RawRowItem(itemRows);
120  ++elemsIndex;
121  }
122 
123  for (int i = 0; i < size2; ++i) {
124  var itemRows = new int[colCount];
125 
126  for (int n = 0; n < colCount; ++n) {
127  itemRows[n] = merge2[n].Rows[i];
128  }
129 
130  elems[elemsIndex] = new RawRowItem(itemRows);
131  ++elemsIndex;
132  }
133 
134  // Now sort the row elements into order.
135 
136  Array.Sort(elems);
137 
138  // Remove any duplicate rows.
139 
140  for (int i = 0; i < colCount; ++i) {
141  merge1[i].Rows.Clear();
142  }
143 
144  RawRowItem previous = null;
145  for (int n = 0; n < mergeSize; ++n) {
146  var current = elems[n];
147 
148  // Check that the current element in the set is not a duplicate of the
149  // previous.
150 
151  if (previous == null || previous.CompareTo(current) != 0) {
152  for (int i = 0; i < colCount; ++i) {
153  merge1[i].Rows.Add(current.RowValues[i]);
154  }
155  previous = current;
156  }
157  }
158 
159  for (int i = 0; i < colCount; ++i) {
160  resultItems.Add(merge1[i]);
161  }
162 
163  return new RawTableInfo(resultItems.ToArray());
164  }
165 
167  // If no tables in duplicate then return
168 
169  if (tableItems.Count == 0)
170  return new RawTableInfo();
171 
172  // Get the length of the first row set in the first table. We assume that
173  // the row set length is identical across each table in the Vector.
174 
175  var elen = tableItems[0];
176  int len = elen.Rows.Count;
177  if (len == 0)
178  return new RawTableInfo(tableItems.ToArray());
179 
180  // Create a new row element to sort.
181 
182  var elems = new RawRowItem[len];
183  int width = tableItems.Count;
184 
185  // Create an array of RawTableElement so we can quickly access the data
186 
187  var rdup = new RawTableItem[width];
188  tableItems.CopyTo(rdup);
189 
190  // Run through the data building up a new RawTableElement[] array with
191  // the information in every raw span.
192 
193  for (int i = 0; i < len; ++i) {
194  var itemRows = new int[width];
195  for (int n = 0; n < width; ++n) {
196  itemRows[n] = rdup[n].Rows[i];
197  }
198  elems[i] = new RawRowItem(itemRows);
199  }
200 
201  // Now 'elems' it an array of individual RawRowItem objects which
202  // represent each individual row in the table.
203 
204  // Now sort and remove duplicates to make up a new set.
205 
206  Array.Sort(elems);
207 
208  var resultTables = new List<RawTableItem>();
209 
210  // Make a new set of RawTableElement[] objects
211 
212  var items = rdup;
213 
214  // Set up the 'raw_info' vector with the new RawTableElement[] removing
215  // any duplicate rows.
216 
217  for (int i = 0; i < width; ++i) {
218  items[i].Rows.Clear();
219  }
220 
221  RawRowItem previous = null;
222  for (int n = 0; n < len; ++n) {
223  var current = elems[n];
224 
225  // Check that the current element in the set is not a duplicate of the
226  // previous.
227 
228  if (previous == null || previous.CompareTo(current) != 0) {
229  for (int i = 0; i < width; ++i) {
230  items[i].Rows.Add(current.RowValues[i]);
231  }
232  previous = current;
233  }
234  }
235 
236  for (int i = 0; i < width; ++i) {
237  resultTables.Add(items[i]);
238  }
239 
240  return new RawTableInfo(resultTables.ToArray());
241  }
242 
243 
244  #region RawTableItem
245 
246  class RawTableItem : IComparable<RawTableItem> {
247  public RawTableItem(IRootTable table)
248  : this(table, new List<int>()) {
249  }
250 
251  public RawTableItem(IRootTable table, IList<int> rows) {
252  Table = table;
253  Rows = new List<int>(rows);
254  }
255 
256  public IRootTable Table { get; private set; }
257 
258  public IList<int> Rows { get; private set; }
259 
260  public int CompareTo(RawTableItem other) {
261  return Table.GetHashCode() - other.Table.GetHashCode();
262  }
263  }
264 
265  #endregion
266 
267  #region RawRowItem
268 
269  class RawRowItem : IComparable<RawRowItem> {
270  public RawRowItem(int[] values) {
271  RowValues = values;
272  }
273 
274  public int[] RowValues { get; private set; }
275 
276  public int CompareTo(RawRowItem other) {
277  int size = RowValues.Length;
278  for (int i = 0; i < size; ++i) {
279  int v1 = RowValues[i];
280  int v2 = other.RowValues[i];
281  if (v1 != v2) {
282  return v1 - v2;
283  }
284  }
285  return 0;
286  }
287  }
288 
289  #endregion
290  }
291 }
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
readonly List< RawTableItem > tableItems
Definition: RawTableInfo.cs:23
RawTableInfo(IEnumerable< RawTableItem > tableItems)
Definition: RawTableInfo.cs:29
RawTableItem(IRootTable table, IList< int > rows)
RawTableInfo Union(RawTableInfo info)
Definition: RawTableInfo.cs:53
void Add(IRootTable table, IList< int > rowSet)
Definition: RawTableInfo.cs:34
Interface that is implemented by all root tables.
Definition: IRootTable.cs:33