private void WriteSink(DataBlock sender, object Tag)
        {
            object[] d = null;

            lock(CBMap)
            {
                d = (object[])CBMap[Tag];
                //Done
                CBMap.Remove(Tag);
            }
            if(sender._Tag!=null)
            {
                ((OnWriteHandler)sender._Tag)(this,(string)d[0],d[1]);
                sender._Tag = null;
            }
        }
 public void ReadRecord(string KEY, object Tag, OnReadHandler CB)
 {
     object kobj = Map[KEY];
     if(kobj==null)
     {
         if(CB!=null) CB(this,KEY,new byte[0],Tag);
         return;
     }
     else
     {
         int i = (int)kobj;
         DataBlock d = new DataBlock(this,i,new DataBlock.OnReadHandler(ReadDataBlockSink),new object[3]{CB,KEY,Tag});
         PendingReadTable[d] = d;
     }
 }
 private void ReadDataBlockSink(DataBlock sender, string key, byte[] ReadBuffer, object Tag)
 {
     PendingReadTable.Remove(sender);
     object[] State = (object[])Tag;
     OnReadHandler CB = (OnReadHandler)State[0];
     string KEY = (string)State[1];
     object _Tag = State[2];
     if(CB!=null) CB(this,KEY,ReadBuffer,_Tag);
 }
 public void ReadRecord(int Position, object Tag, OnReadHandler CB)
 {
     DataBlock d = new DataBlock(this,Position,new DataBlock.OnReadHandler(ReadDataBlockSink),new object[3]{CB,"",Tag});
     PendingReadTable[d] = d;
 }
 public DataBlock GetFreeBlock()
 {
     DataBlock RetVal = null;
     lock(FreeBlockList)
     {
         if(FreeBlockList.Count!=0)
         {
             RetVal = new DataBlock((int)FreeBlockList.GetKey(0),this);
             FreeBlockList.RemoveAt(0);
         }
         else
         {
             RetVal = new DataBlock(EPtr,this);
             EPtr += 512;
         }
     }
     return(RetVal);
 }
 public void AddFreeBlock(DataBlock b)
 {
     AddFreeBlock(b.OFFSET);
 }
        public void Write(string KEY, byte[] DataBuffer, int offset, int count, object Tag)
        {
            UTF8Encoding U = new UTF8Encoding();

            byte[] key     = U.GetBytes(KEY);
            byte[] keysize = BitConverter.GetBytes((short)key.Length);
            byte[] Fill    = null;

            int DataIDX     = 0;
            int DataWritten = 0;
            int DataWrite   = 0;

            byte[] BlockSize = null;
            byte[] NextBlock = null;

            DataBlock OtherBlock = null;

            f.SeekLock.WaitOne();
            f.fstream.Seek(OFFSET + 2, SeekOrigin.Begin);
            Interlocked.Increment(ref PendingWrites);
            f.fstream.BeginWrite(keysize, 0, 2, CB, Tag);
            Interlocked.Increment(ref PendingWrites);
            f.fstream.BeginWrite(key, 0, key.Length, CB, Tag);

            if (key.Length + 8 < f.MaxBlockSize)
            {
                // Can fit data here
                if (DataBuffer.Length > (f.MaxBlockSize - key.Length - 8))
                {
                    DataWrite = f.MaxBlockSize - key.Length - 8;
                }
                else
                {
                    DataWrite = DataBuffer.Length;
                }
                Interlocked.Increment(ref PendingWrites);
                f.fstream.BeginWrite(DataBuffer, 0, DataWrite, CB, Tag);
                DataWritten += DataWrite;
                DataIDX     += DataWrite;
                Fill         = new Byte[(int)f.MaxBlockSize - (DataWrite + key.Length) - 8];
                if (Fill.Length > 0)
                {
                    Interlocked.Increment(ref PendingWrites);
                    f.fstream.BeginWrite(Fill, 0, Fill.Length, CB, Tag);
                }
                BlockSize = BitConverter.GetBytes((short)(DataWrite + key.Length));
            }
            else
            {
                BlockSize = BitConverter.GetBytes((short)key.Length);
            }

            f.fstream.Seek((long)OFFSET, SeekOrigin.Begin);
            Interlocked.Increment(ref PendingWrites);
            f.fstream.BeginWrite(BlockSize, 0, 2, CB, Tag);
            if (DataBuffer.Length - DataWrite == 0)
            {
                // No need for more packets;
                NextBlock = BitConverter.GetBytes((int)-1);
                f.fstream.Seek((long)OFFSET + (long)(f.MaxBlockSize - 4), SeekOrigin.Begin);
                Interlocked.Increment(ref PendingWrites);
                f.fstream.BeginWrite(NextBlock, 0, 4, CB, Tag);
                f.SeekLock.ReleaseMutex();
                if (Interlocked.Decrement(ref PendingWrites) == 0)
                {
                    if (OnWrite != null)
                    {
                        OnWrite(this, Tag);
                    }
                }
                return;
            }

            // Need More Blocks
            keysize = BitConverter.GetBytes((short)0);
            f.SeekLock.ReleaseMutex();
            while (DataBuffer.Length - DataWritten != 0)
            {
                OtherBlock = f.GetFreeBlock();
                NextBlock  = BitConverter.GetBytes(OtherBlock.OFFSET);
                f.SeekLock.WaitOne();
                f.fstream.Seek((long)OFFSET + (long)(f.MaxBlockSize - 4), SeekOrigin.Begin);
                Interlocked.Increment(ref PendingWrites);
                f.fstream.BeginWrite(NextBlock, 0, 4, CB, Tag);

                OFFSET = OtherBlock.OFFSET;
                f.fstream.Seek((long)OFFSET + 2, SeekOrigin.Begin);
                Interlocked.Increment(ref PendingWrites);
                f.fstream.BeginWrite(keysize, 0, 2, CB, Tag);

                if (DataBuffer.Length - DataWritten > (int)(f.MaxBlockSize - 8))
                {
                    DataWrite = f.MaxBlockSize - 8;
                }
                else
                {
                    DataWrite = DataBuffer.Length - DataWritten;
                }
                Interlocked.Increment(ref PendingWrites);
                f.fstream.BeginWrite(DataBuffer, DataIDX, DataWrite, CB, Tag);
                DataWritten += DataWrite;
                DataIDX     += DataWrite;
                Fill         = new byte[(int)f.MaxBlockSize - DataWrite - 8];
                if (Fill.Length > 0)
                {
                    Interlocked.Increment(ref PendingWrites);
                    f.fstream.BeginWrite(Fill, 0, Fill.Length, CB, Tag);
                }
                BlockSize = BitConverter.GetBytes((short)DataWrite);
                f.fstream.Seek((long)OFFSET, SeekOrigin.Begin);
                Interlocked.Increment(ref PendingWrites);
                f.fstream.BeginWrite(BlockSize, 0, 2, CB, Tag);
                if (DataBuffer.Length - DataWritten == 0)
                {
                    f.fstream.Seek((long)OFFSET + (long)(f.MaxBlockSize - 4), SeekOrigin.Begin);
                    NextBlock = BitConverter.GetBytes((int)-1);
                    Interlocked.Increment(ref PendingWrites);
                    f.fstream.BeginWrite(NextBlock, 0, 4, CB, Tag);
                }
                f.SeekLock.ReleaseMutex();
            }

            if (Interlocked.Decrement(ref PendingWrites) == 0)
            {
                if (OnWrite != null)
                {
                    OnWrite(this, Tag);
                }
            }
        }
 public void AddFreeBlock(DataBlock b)
 {
     AddFreeBlock(b.OFFSET);
 }