Click here to Skip to main content
15,886,110 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.5K   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 System;
using System.Text;
using Db4objects.Db4o.Foundation;
using Db4objects.Db4o.Internal;
using Db4objects.Db4o.Internal.Freespace;
using Db4objects.Db4o.Internal.Slots;

namespace Db4objects.Db4o.Internal.Freespace
{
	public class RamFreespaceManager : AbstractFreespaceManager
	{
		private readonly TreeIntObject _finder = new TreeIntObject(0);

		private Tree _freeByAddress;

		private Tree _freeBySize;

		public RamFreespaceManager(LocalObjectContainer file) : base(file)
		{
		}

		private void AddFreeSlotNodes(int address, int length)
		{
			FreeSlotNode addressNode = new FreeSlotNode(address);
			addressNode.CreatePeer(length);
			_freeByAddress = Tree.Add(_freeByAddress, addressNode);
			_freeBySize = Tree.Add(_freeBySize, addressNode._peer);
		}

		public override Slot AllocateTransactionLogSlot(int length)
		{
			FreeSlotNode sizeNode = (FreeSlotNode)Tree.Last(_freeBySize);
			if (sizeNode == null || sizeNode._key < length)
			{
				return null;
			}
			int limit = length + 100;
			if (sizeNode._key > limit)
			{
				return GetSlot(limit);
			}
			RemoveFromBothTrees(sizeNode);
			return new Slot(sizeNode._peer._key, sizeNode._key);
		}

		public override void FreeTransactionLogSlot(Slot slot)
		{
			Free(slot);
		}

		public override void BeginCommit()
		{
		}

		public override void Commit()
		{
		}

		public override void EndCommit()
		{
		}

		public override void Free(Slot slot)
		{
			int address = slot.Address();
			int length = slot.Length();
			if (address <= 0)
			{
				throw new ArgumentException();
			}
			_finder._key = address;
			FreeSlotNode sizeNode;
			FreeSlotNode addressnode = (FreeSlotNode)Tree.FindSmaller(_freeByAddress, _finder
				);
			if ((addressnode != null) && ((addressnode._key + addressnode._peer._key) == address
				))
			{
				sizeNode = addressnode._peer;
				_freeBySize = _freeBySize.RemoveNode(sizeNode);
				sizeNode._key += length;
				FreeSlotNode secondAddressNode = (FreeSlotNode)Tree.FindGreaterOrEqual(_freeByAddress
					, _finder);
				if ((secondAddressNode != null) && (address + length == secondAddressNode._key))
				{
					sizeNode._key += secondAddressNode._peer._key;
					RemoveFromBothTrees(secondAddressNode._peer);
				}
				sizeNode.RemoveChildren();
				_freeBySize = Tree.Add(_freeBySize, sizeNode);
			}
			else
			{
				addressnode = (FreeSlotNode)Tree.FindGreaterOrEqual(_freeByAddress, _finder);
				if ((addressnode != null) && (address + length == addressnode._key))
				{
					sizeNode = addressnode._peer;
					RemoveFromBothTrees(sizeNode);
					sizeNode._key += length;
					addressnode._key = address;
					addressnode.RemoveChildren();
					sizeNode.RemoveChildren();
					_freeByAddress = Tree.Add(_freeByAddress, addressnode);
					_freeBySize = Tree.Add(_freeBySize, sizeNode);
				}
				else
				{
					if (CanDiscard(length))
					{
						return;
					}
					AddFreeSlotNodes(address, length);
				}
			}
			_file.OverwriteDeletedBlockedSlot(slot);
		}

		public override void FreeSelf()
		{
		}

		private void FreeReader(StatefulBuffer reader)
		{
			_file.Free(reader.GetAddress(), reader.GetLength());
		}

		public override Slot GetSlot(int length)
		{
			_finder._key = length;
			_finder._object = null;
			_freeBySize = FreeSlotNode.RemoveGreaterOrEqual((FreeSlotNode)_freeBySize, _finder
				);
			if (_finder._object == null)
			{
				return null;
			}
			FreeSlotNode node = (FreeSlotNode)_finder._object;
			int blocksFound = node._key;
			int address = node._peer._key;
			_freeByAddress = _freeByAddress.RemoveNode(node._peer);
			int remainingBlocks = blocksFound - length;
			if (CanDiscard(remainingBlocks))
			{
				length = blocksFound;
			}
			else
			{
				AddFreeSlotNodes(address + length, remainingBlocks);
			}
			return new Slot(address, length);
		}

		internal virtual int MarshalledLength()
		{
			return TreeInt.MarshalledLength((TreeInt)_freeBySize);
		}

		public override int OnNew(LocalObjectContainer file)
		{
			return 0;
		}

		public override void Read(int freeSlotsID)
		{
			ReadById(freeSlotsID);
		}

		private void Read(StatefulBuffer reader)
		{
			FreeSlotNode.sizeLimit = BlockedDiscardLimit();
			_freeBySize = new TreeReader(reader, new FreeSlotNode(0), true).Read();
			Tree.ByRef addressTree = new Tree.ByRef();
			if (_freeBySize != null)
			{
				_freeBySize.Traverse(new _AnonymousInnerClass173(this, addressTree));
			}
			_freeByAddress = addressTree.value;
		}

		private sealed class _AnonymousInnerClass173 : IVisitor4
		{
			public _AnonymousInnerClass173(RamFreespaceManager _enclosing, Tree.ByRef addressTree
				)
			{
				this._enclosing = _enclosing;
				this.addressTree = addressTree;
			}

			public void Visit(object a_object)
			{
				FreeSlotNode node = ((FreeSlotNode)a_object)._peer;
				addressTree.value = Tree.Add(addressTree.value, node);
			}

			private readonly RamFreespaceManager _enclosing;

			private readonly Tree.ByRef addressTree;
		}

		internal virtual void Read(Slot slot)
		{
			if (slot.Address() == 0)
			{
				return;
			}
			StatefulBuffer reader = _file.ReadWriterByAddress(Transaction(), slot.Address(), 
				slot.Length());
			if (reader == null)
			{
				return;
			}
			Read(reader);
			FreeReader(reader);
		}

		private void ReadById(int freeSlotsID)
		{
			if (freeSlotsID <= 0)
			{
				return;
			}
			if (DiscardLimit() == int.MaxValue)
			{
				return;
			}
			StatefulBuffer reader = _file.ReadWriterByID(Transaction(), freeSlotsID);
			if (reader == null)
			{
				return;
			}
			Read(reader);
			_file.Free(freeSlotsID, Const4.POINTER_LENGTH);
			FreeReader(reader);
		}

		private void RemoveFromBothTrees(FreeSlotNode sizeNode)
		{
			_freeBySize = _freeBySize.RemoveNode(sizeNode);
			_freeByAddress = _freeByAddress.RemoveNode(sizeNode._peer);
		}

		public override int SlotCount()
		{
			return Tree.Size(_freeByAddress);
		}

		public override void Start(int slotAddress)
		{
		}

		public override byte SystemType()
		{
			return FM_RAM;
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("RAM FreespaceManager\n");
			sb.Append("Address Index\n");
			_freeByAddress.Traverse(new _AnonymousInnerClass236(this, sb));
			sb.Append("Length Index\n");
			_freeBySize.Traverse(new _AnonymousInnerClass244(this, sb));
			return sb.ToString();
		}

		private sealed class _AnonymousInnerClass236 : IVisitor4
		{
			public _AnonymousInnerClass236(RamFreespaceManager _enclosing, StringBuilder sb)
			{
				this._enclosing = _enclosing;
				this.sb = sb;
			}

			public void Visit(object obj)
			{
				sb.Append(obj);
				sb.Append("\n");
			}

			private readonly RamFreespaceManager _enclosing;

			private readonly StringBuilder sb;
		}

		private sealed class _AnonymousInnerClass244 : IVisitor4
		{
			public _AnonymousInnerClass244(RamFreespaceManager _enclosing, StringBuilder sb)
			{
				this._enclosing = _enclosing;
				this.sb = sb;
			}

			public void Visit(object obj)
			{
				sb.Append(obj);
				sb.Append("\n");
			}

			private readonly RamFreespaceManager _enclosing;

			private readonly StringBuilder sb;
		}

		public override void Traverse(IVisitor4 visitor)
		{
			if (_freeByAddress == null)
			{
				return;
			}
			_freeByAddress.Traverse(new _AnonymousInnerClass257(this, visitor));
		}

		private sealed class _AnonymousInnerClass257 : IVisitor4
		{
			public _AnonymousInnerClass257(RamFreespaceManager _enclosing, IVisitor4 visitor)
			{
				this._enclosing = _enclosing;
				this.visitor = visitor;
			}

			public void Visit(object a_object)
			{
				FreeSlotNode fsn = (FreeSlotNode)a_object;
				int address = fsn._key;
				int length = fsn._peer._key;
				visitor.Visit(new Slot(address, length));
			}

			private readonly RamFreespaceManager _enclosing;

			private readonly IVisitor4 visitor;
		}

		public override int Write()
		{
			Pointer4 pointer = _file.NewSlot(MarshalledLength());
			Write(pointer);
			return pointer._id;
		}

		internal virtual void Write(Pointer4 pointer)
		{
			StatefulBuffer buffer = new StatefulBuffer(Transaction(), pointer);
			TreeInt.Write(buffer, (TreeInt)_freeBySize);
			buffer.WriteEncrypt();
			Transaction().FlushFile();
			Transaction().WritePointer(pointer);
		}
	}
}

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