Click here to Skip to main content
15,893,722 members
Articles / Programming Languages / C#

Using a Database Over a Webservice

Rate me:
Please Sign up or sign in to vote.
4.43/5 (5 votes)
29 May 20073 min read 48.6K   539   44  
This article shows an example implementation of a database used over a Web-Service
/* Copyright (C) 2004 - 2007  db4objects Inc.  http://www.db4o.com */

using Db4objects.Db4o.Foundation;
using Db4objects.Db4o.Internal;
using Db4objects.Db4o.Internal.IX;

namespace Db4objects.Db4o.Internal.IX
{
	/// <exclude></exclude>
	internal class IxFileRangeReader
	{
		private int _baseAddress;

		private int _baseAddressOffset;

		private int _addressOffset;

		private readonly IIndexable4 _handler;

		private int _lower;

		private int _upper;

		private int _cursor;

		private readonly Db4objects.Db4o.Internal.Buffer _reader;

		internal readonly int _slotLength;

		internal readonly int _linkLegth;

		internal IxFileRangeReader(IIndexable4 handler)
		{
			_handler = handler;
			_linkLegth = handler.LinkLength();
			_slotLength = _linkLegth + Const4.INT_LENGTH;
			_reader = new Db4objects.Db4o.Internal.Buffer(_slotLength);
		}

		internal virtual Tree Add(IxFileRange fileRange, Tree newTree)
		{
			SetFileRange(fileRange);
			LocalObjectContainer yf = fileRange.Stream();
			Transaction trans = fileRange.Trans();
			while (true)
			{
				int offset = _baseAddressOffset + _addressOffset;
				_reader.Read(yf, _baseAddress, offset);
				_reader._offset = 0;
				int cmp = Compare(trans);
				if (cmp == 0)
				{
					int parentID = _reader.ReadInt();
					cmp = parentID - ((IxPatch)newTree)._parentID;
				}
				if (cmp > 0)
				{
					_upper = _cursor - 1;
					if (_upper < _lower)
					{
						_upper = _lower;
					}
				}
				else
				{
					if (cmp < 0)
					{
						_lower = _cursor + 1;
						if (_lower > _upper)
						{
							_lower = _upper;
						}
					}
					else
					{
						if (newTree is IxRemove)
						{
							if (_cursor == 0)
							{
								newTree._preceding = fileRange._preceding;
								if (fileRange._entries == 1)
								{
									newTree._subsequent = fileRange._subsequent;
									return newTree.BalanceCheckNulls();
								}
								fileRange._entries--;
								fileRange.IncrementAddress(_slotLength);
								fileRange._preceding = null;
								newTree._subsequent = fileRange;
							}
							else
							{
								if (_cursor + 1 == fileRange._entries)
								{
									newTree._preceding = fileRange;
									newTree._subsequent = fileRange._subsequent;
									fileRange._subsequent = null;
									fileRange._entries--;
								}
								else
								{
									return Insert(fileRange, newTree, _cursor, 0);
								}
							}
							fileRange.CalculateSize();
							return newTree.BalanceCheckNulls();
						}
						if (_cursor == 0)
						{
							newTree._subsequent = fileRange;
							return newTree.RotateLeft();
						}
						else
						{
							if (_cursor == fileRange._entries)
							{
								newTree._preceding = fileRange;
								return newTree.RotateRight();
							}
						}
						return Insert(fileRange, newTree, _cursor, cmp);
					}
				}
				if (!AdjustCursor())
				{
					if (_cursor == 0 && cmp > 0)
					{
						return fileRange.Add(newTree, 1);
					}
					if (_cursor == fileRange._entries - 1 && cmp < 0)
					{
						return fileRange.Add(newTree, -1);
					}
					return Insert(fileRange, newTree, _cursor, cmp);
				}
			}
		}

		private bool AdjustCursor()
		{
			if (_upper < _lower)
			{
				return false;
			}
			int oldCursor = _cursor;
			_cursor = _lower + ((_upper - _lower) / 2);
			if (_cursor == oldCursor && _cursor == _lower && _lower < _upper)
			{
				_cursor++;
			}
			_addressOffset = _cursor * _slotLength;
			return _cursor != oldCursor;
		}

		internal virtual int Compare(IxFileRange fileRange, int[] matches)
		{
			SetFileRange(fileRange);
			LocalObjectContainer yf = fileRange.Stream();
			Transaction trans = fileRange.Trans();
			int res = 0;
			while (true)
			{
				int offset = _baseAddressOffset + _addressOffset;
				_reader.Read(yf, _baseAddress, offset);
				_reader._offset = 0;
				int cmp = Compare(trans);
				if (cmp > 0)
				{
					_upper = _cursor - 1;
				}
				else
				{
					if (cmp < 0)
					{
						_lower = _cursor + 1;
					}
					else
					{
						break;
					}
				}
				if (!AdjustCursor())
				{
					if (_cursor <= 0)
					{
						if (!(cmp < 0 && fileRange._entries > 1))
						{
							res = cmp;
						}
					}
					else
					{
						if (_cursor >= (fileRange._entries - 1))
						{
							if (cmp < 0)
							{
								res = cmp;
							}
						}
					}
					break;
				}
			}
			matches[0] = _lower;
			matches[1] = _upper;
			if (_lower > _upper)
			{
				return res;
			}
			int tempCursor = _cursor;
			_upper = _cursor;
			AdjustCursor();
			while (true)
			{
				int offset = _baseAddressOffset + _addressOffset;
				_reader.Read(yf, _baseAddress, offset);
				_reader._offset = 0;
				int cmp = Compare(trans);
				if (cmp == 0)
				{
					_upper = _cursor;
				}
				else
				{
					_lower = _cursor + 1;
					if (_lower > _upper)
					{
						matches[0] = _upper;
						break;
					}
				}
				if (!AdjustCursor())
				{
					matches[0] = _upper;
					break;
				}
			}
			_upper = matches[1];
			_lower = tempCursor;
			if (_lower > _upper)
			{
				_lower = _upper;
			}
			AdjustCursor();
			while (true)
			{
				int offset = _baseAddressOffset + _addressOffset;
				_reader.Read(yf, _baseAddress, offset);
				_reader._offset = 0;
				int cmp = Compare(trans);
				if (cmp == 0)
				{
					_lower = _cursor;
				}
				else
				{
					_upper = _cursor - 1;
					if (_upper < _lower)
					{
						matches[1] = _lower;
						break;
					}
				}
				if (!AdjustCursor())
				{
					matches[1] = _lower;
					break;
				}
			}
			return res;
		}

		private int Compare(Transaction trans)
		{
			return _handler.CompareTo(_handler.ComparableObject(trans, _handler.ReadIndexEntry
				(_reader)));
		}

		private Tree Insert(IxFileRange fileRange, Tree a_new, int a_cursor, int a_cmp)
		{
			int incStartNewAt = a_cmp <= 0 ? 1 : 0;
			int newAddressOffset = (a_cursor + incStartNewAt) * _slotLength;
			int newEntries = fileRange._entries - a_cursor - incStartNewAt;
			fileRange._entries = a_cmp < 0 ? a_cursor + 1 : a_cursor;
			IxFileRange ifr = new IxFileRange(fileRange._fieldTransaction, _baseAddress, _baseAddressOffset
				 + newAddressOffset, newEntries);
			ifr._subsequent = fileRange._subsequent;
			fileRange._subsequent = null;
			a_new._preceding = fileRange.BalanceCheckNulls();
			a_new._subsequent = ifr.BalanceCheckNulls();
			return a_new.Balance();
		}

		private void SetFileRange(IxFileRange a_fr)
		{
			_lower = 0;
			_upper = a_fr._entries - 1;
			_baseAddress = a_fr._address;
			_baseAddressOffset = a_fr._addressOffset;
			AdjustCursor();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United Arab Emirates United Arab Emirates
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions