DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
TableStateStore.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.IO;
20 using System.Linq;
21 using System.Text;
22 
23 using Deveel.Data.Store;
24 
25 namespace Deveel.Data {
27  private IArea headerArea;
28 
29  private long delAreaPointer;
30  private List<TableState> deleteList;
31  private bool delListChange;
32 
33  private long visAreaPointer;
34  private List<TableState> visibleList;
35  private bool visListChange;
36 
37  private int currentTableId;
38 
39  private const int Magic = 0x0BAC8001;
40 
41  public TableStateStore(IStore store) {
42  if (store == null)
43  throw new ArgumentNullException("store");
44 
45  Store = store;
46  }
47 
48  public IStore Store { get; private set; }
49 
50  private void ReadStateResourceList(IList<TableState> list, long pointer) {
51  using (var reader = new BinaryReader(Store.GetAreaInputStream(pointer), Encoding.Unicode)) {
52  reader.ReadInt32(); // version
53 
54  int count = (int) reader.ReadInt64();
55  for (int i = 0; i < count; ++i) {
56  long tableId = reader.ReadInt64();
57  string name = reader.ReadString();
58 
59  list.Add(new TableState((int)tableId, name));
60  }
61  }
62  }
63 
64  private static byte[] SerializeResources(IEnumerable<TableState> list) {
65  using (var stream = new MemoryStream()) {
66  using (var writer = new BinaryWriter(stream, Encoding.Unicode)) {
67  writer.Write(1); // version
68  int sz = list.Count();
69  writer.Write((long) sz);
70  foreach (var state in list) {
71  writer.Write((long)state.TableId);
72  writer.Write(state.SourceName);
73  }
74 
75  writer.Flush();
76 
77  return stream.ToArray();
78  }
79  }
80  }
81 
82  private long WriteListToStore(IEnumerable<TableState> list) {
83  var bytes = SerializeResources(list);
84 
85  var area = Store.CreateArea(bytes.Length);
86  long listP = area.Id;
87  area.Write(bytes, 0, bytes.Length);
88  area.Flush();
89 
90  return listP;
91  }
92 
93  public long Create() {
94  lock (this) {
95  // Allocate empty visible and deleted tables area
96  var visTablesArea = Store.CreateArea(12);
97  var delTablesArea = Store.CreateArea(12);
98  visAreaPointer = visTablesArea.Id;
99  delAreaPointer = delTablesArea.Id;
100 
101  // Write empty entries for both of these
102  visTablesArea.WriteInt4(1);
103  visTablesArea.WriteInt8(0);
104  visTablesArea.Flush();
105  delTablesArea.WriteInt4(1);
106  delTablesArea.WriteInt8(0);
107  delTablesArea.Flush();
108 
109  // Now allocate an empty state header
110  var headerWriter = Store.CreateArea(32);
111  long headerP = headerWriter.Id;
112  headerWriter.WriteInt4(Magic);
113  headerWriter.WriteInt4(0);
114  headerWriter.WriteInt8(0);
115  headerWriter.WriteInt8(visAreaPointer);
116  headerWriter.WriteInt8(delAreaPointer);
117  headerWriter.Flush();
118 
119  headerArea = Store.GetArea(headerP, false);
120 
121  // Reset currentTableId
122  currentTableId = 0;
123 
124  visibleList = new List<TableState>();
125  deleteList = new List<TableState>();
126 
127  // Return pointer to the header area
128  return headerP;
129  }
130  }
131 
132  public void Open(long offset) {
133  lock (this) {
134  headerArea = Store.GetArea(offset);
135  int magicValue = headerArea.ReadInt4();
136  if (magicValue != Magic)
137  throw new IOException("Magic value for state header area is incorrect.");
138 
139  if (headerArea.ReadInt4() != 0)
140  throw new IOException("Unknown version for state header area.");
141 
142  currentTableId = (int)headerArea.ReadInt8();
143  visAreaPointer = headerArea.ReadInt8();
144  delAreaPointer = headerArea.ReadInt8();
145 
146  // Setup the visible and delete list
147  visibleList = new List<TableState>();
148  deleteList = new List<TableState>();
149 
150  // Read the resource list for the visible and delete list.
151  ReadStateResourceList(visibleList, visAreaPointer);
152  ReadStateResourceList(deleteList, delAreaPointer);
153  }
154  }
155 
156  public int NextTableId() {
157  lock (this) {
158  int curCounter = currentTableId;
159  ++currentTableId;
160 
161  try {
162  Store.Lock();
163 
164  // Update the state in the file
165  headerArea.Position = 8;
166  headerArea.WriteInt8(currentTableId);
167 
168  // Check out the change
169  headerArea.Flush();
170  } finally {
171  Store.Unlock();
172  }
173 
174  return curCounter;
175  }
176  }
177 
178  public IEnumerable<TableState> GetVisibleList() {
179  lock (this) {
180  return visibleList.AsEnumerable();
181  }
182  }
183 
184  public IEnumerable<TableState> GetDeleteList() {
185  lock (this) {
186  return deleteList.AsEnumerable();
187  }
188  }
189 
190  public bool ContainsVisibleResource(int tableId) {
191  lock (this) {
192  foreach (var resource in visibleList) {
193  if (resource.TableId == tableId)
194  return true;
195  }
196  return false;
197  }
198  }
199 
200  public void AddVisibleResource(TableState resource) {
201  lock (this) {
202  visibleList.Add(resource);
203  visListChange = true;
204  }
205  }
206 
207  public void AddDeleteResource(TableState resource) {
208  lock (this) {
209  deleteList.Add(resource);
210  delListChange = true;
211  }
212  }
213 
214  public void RemoveVisibleResource(string name) {
215  lock (this) {
216  RemoveState(visibleList, name);
217  visListChange = true;
218  }
219  }
220 
221  public void RemoveDeleteResource(string name) {
222  lock (this) {
223  RemoveState(deleteList, name);
224  delListChange = true;
225  }
226  }
227 
228  private static void RemoveState(IList<TableState> list, String name) {
229  int sz = list.Count;
230  for (int i = 0; i < sz; ++i) {
231  var state = list[i];
232  if (name.Equals(state.SourceName)) {
233  list.RemoveAt(i);
234  return;
235  }
236  }
237  throw new Exception("Couldn't find resource '" + name + "' in list.");
238  }
239 
240  public void Flush() {
241  lock (this) {
242  bool changes = false;
243  long newVisP = visAreaPointer;
244  long newDelP = delAreaPointer;
245 
246  try {
247  Store.Lock();
248 
249  // If the lists changed, then Write new state areas to the store.
250  if (visListChange) {
251  newVisP = WriteListToStore(visibleList);
252  visListChange = false;
253  changes = true;
254  }
255  if (delListChange) {
256  newDelP = WriteListToStore(deleteList);
257  delListChange = false;
258  changes = true;
259  }
260 
261  // Commit the changes,
262  if (changes) {
263  headerArea.Position = 16;
264  headerArea.WriteInt8(newVisP);
265  headerArea.WriteInt8(newDelP);
266  headerArea.Flush();
267 
268  if (visAreaPointer != newVisP) {
269  Store.DeleteArea(visAreaPointer);
270  visAreaPointer = newVisP;
271  }
272 
273  if (delAreaPointer != newDelP) {
274  Store.DeleteArea(delAreaPointer);
275  delAreaPointer = newDelP;
276  }
277  }
278  } finally {
279  Store.Unlock();
280  }
281  }
282  }
283 
284  #region TableState
285 
286  public class TableState {
287  public TableState(int tableId, string sourceName) {
288  TableId = tableId;
289  SourceName = sourceName;
290  }
291 
292  public int TableId { get; private set; }
293 
294  public string SourceName { get; private set; }
295  }
296 
297  #endregion
298  }
299 }
long WriteListToStore(IEnumerable< TableState > list)
void AddDeleteResource(TableState resource)
long Position
Returns or sets the current position of the pointer within the area.
Definition: IArea.cs:48
TableState(int tableId, string sourceName)
void RemoveDeleteResource(string name)
IEnumerable< TableState > GetVisibleList()
bool ContainsVisibleResource(int tableId)
List< TableState > deleteList
void AddVisibleResource(TableState resource)
void RemoveVisibleResource(string name)
An interface for access the contents of an area of a store.
Definition: IArea.cs:23
IEnumerable< TableState > GetDeleteList()
static byte[] SerializeResources(IEnumerable< TableState > list)
List< TableState > visibleList
static void RemoveState(IList< TableState > list, String name)
A store is a resource where areas can be allocated and freed to store information (a memory allocator...
Definition: IStore.cs:56
void ReadStateResourceList(IList< TableState > list, long pointer)