DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
CollatedSearchIndex.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 
20 using Deveel.Data.Sql;
21 using Deveel.Data.Sql.Tables;
22 
23 namespace Deveel.Data.Index {
24  public abstract class CollatedSearchIndex : ColumnIndex {
25  protected CollatedSearchIndex(ITable table, int columnOffset)
26  : base(table, columnOffset) {
27  }
28 
29  protected virtual int Count {
30  get { return Table.RowCount; }
31  }
32 
33  protected virtual DataObject First {
34  get { return GetValue(0); }
35  }
36 
37  protected virtual DataObject Last {
38  get { return GetValue(Count - 1); }
39  }
40 
41  private void AssertNotReadOnly() {
42  if (IsReadOnly)
43  throw new InvalidOperationException("The index is read-only");
44  }
45 
46  public override void Insert(int rowNumber) {
47  AssertNotReadOnly();
48  }
49 
50  public override void Remove(int rowNumber) {
51  AssertNotReadOnly();
52  }
53 
54  protected override void Dispose(bool disposing) {
55  }
56 
57  protected abstract int SearchFirst(DataObject value);
58 
59  protected abstract int SearchLast(DataObject value);
60 
61  protected virtual IEnumerable<int> AddRange(int start, int end, IEnumerable<int> input) {
62  var list = new List<int>((end - start) + 2);
63  if (input != null)
64  list.AddRange(input);
65 
66  for (int i = start; i <= end; ++i) {
67  list.Add(i);
68  }
69 
70  return list;
71  }
72 
73  private IEnumerable<int> AddRange(IndexRange range, IEnumerable<int> list) {
74  // Select the range specified.
75  var startFlag = range.StartOffset;
76  var start = range.StartValue;
77  var endFlag = range.EndOffset;
78  var end = range.EndValue;
79 
80  int r1 = PositionOfRangePoint(startFlag, start);
81  int r2 = PositionOfRangePoint(endFlag, end);
82 
83  if (r2 < r1)
84  return list;
85 
86  // Add the range to the set
87  return AddRange(r1, r2, list);
88 
89  }
90 
91  public override IEnumerable<int> SelectAll() {
92  return AddRange(0, Count - 1, null);
93  }
94 
95  public override IEnumerable<int> SelectRange(IndexRange[] ranges) {
96  // If no items in the set return an empty set
97  if (Count == 0)
98  return new List<int>(0);
99 
100  IEnumerable<int> list = null;
101  foreach (var range in ranges) {
102  list = AddRange(range, list);
103  }
104 
105  if (list == null)
106  return new List<int>(0);
107 
108  return list;
109  }
110 
111  private int PositionOfRangePoint(RangeFieldOffset position, DataObject val) {
112  int p;
113  DataObject cell;
114 
115  switch (position) {
116 
117  case RangeFieldOffset.FirstValue:
118  if (val.Equals(IndexRange.FirstInSet)) {
119  return 0;
120  }
121  if (val.Equals(IndexRange.LastInSet)) {
122  // Get the last value and search for the first instance of it.
123  cell = Last;
124  } else {
125  cell = val;
126  }
127 
128  p = SearchFirst(cell);
129 
130  // (If value not found)
131  if (p < 0)
132  return -(p + 1);
133 
134  return p;
135 
136  case RangeFieldOffset.LastValue:
137  if (val.Equals(IndexRange.LastInSet))
138  return Count - 1;
139 
140  if (val.Equals(IndexRange.FirstInSet)) {
141  // Get the first value.
142  cell = First;
143  } else {
144  cell = val;
145  }
146 
147  p = SearchLast(cell);
148 
149  // (If value not found)
150  if (p < 0) {
151  return -(p + 1) - 1;
152  }
153  return p;
154 
155  case RangeFieldOffset.BeforeFirstValue:
156  if (val.Equals(IndexRange.FirstInSet))
157  return -1;
158 
159  if (val.Equals(IndexRange.LastInSet)) {
160  // Get the last value and search for the first instance of it.
161  cell = Last;
162  } else {
163  cell = val;
164  }
165 
166  p = SearchFirst(cell);
167  // (If value not found)
168  if (p < 0) {
169  return -(p + 1) - 1;
170  }
171  return p - 1;
172 
173  case RangeFieldOffset.AfterLastValue:
174  if (val.Equals(IndexRange.LastInSet)) {
175  return Count;
176  }
177  if (val.Equals(IndexRange.FirstInSet)) {
178  // Get the first value.
179  cell = First;
180  } else {
181  cell = val;
182  }
183  p = SearchLast(cell);
184  // (If value not found)
185  if (p < 0) {
186  return -(p + 1);
187  }
188  return p + 1;
189 
190  default:
191  throw new InvalidOperationException("Unrecognised position.");
192  }
193 
194  }
195  }
196 }
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
IEnumerable< int > AddRange(IndexRange range, IEnumerable< int > list)
override bool Equals(object obj)
Definition: DataObject.cs:179
Describes the range of values to select from an index.
Definition: IndexRange.cs:38
DataObject EndValue
Gets the last value of the range.
Definition: IndexRange.cs:103
static readonly DataObject FirstInSet
Definition: IndexRange.cs:42
RangeFieldOffset EndOffset
Gets the offset of the last value of the range.
Definition: IndexRange.cs:98
int PositionOfRangePoint(RangeFieldOffset position, DataObject val)
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
DataObject StartValue
Gets the first value of the range.
Definition: IndexRange.cs:93
override void Insert(int rowNumber)
override IEnumerable< int > SelectRange(IndexRange[] ranges)
override void Remove(int rowNumber)
override IEnumerable< int > SelectAll()
static readonly DataObject LastInSet
Definition: IndexRange.cs:47
virtual IEnumerable< int > AddRange(int start, int end, IEnumerable< int > input)
RangeFieldOffset
The absolute offset of a field in a range of a selection.
abstract int RowCount
Definition: Table.cs:67
override void Dispose(bool disposing)
CollatedSearchIndex(ITable table, int columnOffset)
RangeFieldOffset StartOffset
Gets the offset of the first value of the range.
Definition: IndexRange.cs:88