public static async Task <MemoryDatabase> LoadFromAsync(string path, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            MemoryClusterHandler  cluster = null;
            MemoryDatabaseHandler db      = null;

            try
            {
                cluster = new MemoryClusterHandler();
                db      = cluster.OpenDatabase(Guid.Empty);

                // load the snapshot from the disk
                var options = new MemorySnapshotOptions();                 //TODO!
                await db.LoadSnapshotAsync(path, options, cancellationToken);

                return(new MemoryDatabase(new FdbCluster(cluster, ":memory:"), db, "DB", FdbSubspace.Empty, null, false, true));
            }
            catch (Exception)
            {
                if (db != null)
                {
                    db.Dispose();
                }
                if (cluster != null)
                {
                    cluster.Dispose();
                }
                throw;
            }
        }
        public static MemoryDatabase CreateNew(string name, IFdbSubspace globalSpace, bool readOnly)
        {
            globalSpace = globalSpace ?? FdbSubspace.Empty;
            var uid = Guid.NewGuid();

            MemoryClusterHandler  cluster = null;
            MemoryDatabaseHandler db      = null;

            try
            {
                cluster = new MemoryClusterHandler();
                db      = cluster.OpenDatabase(uid);

                // initialize the system keys for this new db
                db.PopulateSystemKeys();

                return(new MemoryDatabase(new FdbCluster(cluster, ":memory:"), db, name, globalSpace, null, readOnly, true));
            }
            catch
            {
                if (db != null)
                {
                    db.Dispose();
                }
                if (cluster != null)
                {
                    cluster.Dispose();
                }
                throw;
            }
        }
Beispiel #3
0
        internal MemoryTransactionHandler(MemoryDatabaseHandler db)
        {
            Contract.Assert(db != null);

            m_db = db;

            Initialize(first: true);
        }
Beispiel #4
0
        public unsafe void Add(ulong sequence, USlice userKey, USlice userValue)
        {
            // allocate the key
            var  tmp = MemoryDatabaseHandler.PackUserKey(m_scratch, userKey);
            Key *key = m_keys.Append(tmp);

            Contract.Assert(key != null, "key == null");

            // allocate the value
            uint   size  = userValue.Count;
            Value *value = m_values.Allocate(size, sequence, null, key);

            Contract.Assert(value != null, "value == null");
            UnmanagedHelpers.CopyUnsafe(&(value->Data), userValue);

            key->Values = value;

            m_list.Add(new IntPtr(key));
        }
 private MemoryDatabase(IFdbCluster cluster, MemoryDatabaseHandler handler, string name, IFdbSubspace globalSpace, IFdbDirectory directory, bool readOnly, bool ownsCluster)
     : base(cluster, handler, name, globalSpace, directory, readOnly, ownsCluster)
 {
     m_handler = handler;
 }
		private MemoryDatabase(IFdbCluster cluster, MemoryDatabaseHandler handler, string name, IFdbSubspace globalSpace, IFdbDirectory directory, bool readOnly, bool ownsCluster)
			: base(cluster, handler, name, globalSpace, directory, readOnly, ownsCluster)
		{
			m_handler = handler;
		}
        public async Task WriteLevelAsync(int level, IntPtr[] segment, CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();

            if (m_jumpTable[level].Value > 0)
            {
                throw new InvalidOperationException("The level has already be written to this snapshot");
            }

            var levelStart = checked (m_file.Length + (uint)m_writer.Position);

            //Console.WriteLine("## level " + level + " starts at " + levelStart);

            //TODO: ensure that we start on a PAGE?

            //Console.WriteLine("> Writing level " + level);

            // "LVL_"
            m_writer.WriteFixed32(SnapshotFormat.LEVEL_MAGIC_NUMBER);
            // Level Flags
            m_writer.WriteFixed32(0);             //TODO: flags!
            // Level ID
            m_writer.WriteFixed32((uint)level);
            // Item count (always 2^level)
            m_writer.WriteFixed32((uint)segment.Length);

            for (int i = 0; i < segment.Length; i++)
            {
                unsafe
                {
#if __MonoCS__
                    var valuePointer = new IntPtr((void *)MemoryDatabaseHandler.ResolveValueAtVersion(segment[i], m_sequence));

                    if (valuePointer == IntPtr.Zero)
                    {
                        continue;
                    }

                    Value value = new Value();
                    Marshal.PtrToStructure(valuePointer, value);

                    var keyPointer = new IntPtr((void *)segment[i]);

                    Key key = new Key();
                    Marshal.PtrToStructure(keyPointer, key);

                    Contract.Assert(key.Size <= MemoryDatabaseHandler.MAX_KEY_SIZE);

                    // Key Size
                    uint size = key.Size;
                    m_writer.WriteVarint32(size);
                    m_writer.WriteBytesUnsafe(&(key.Data), (int)size);

                    // Value
                    m_writer.WriteVarint64(value.Sequence);                     // sequence
                    size = value.Size;
                    if (size == 0)
                    {                     // empty key
                        m_writer.WriteByte(0);
                    }
                    else
                    {
                        m_writer.WriteVarint32(size);                         // value size
                        m_writer.WriteBytesUnsafe(&(value.Data), (int)size);  // value data
                    }
#else
                    Value *value = MemoryDatabaseHandler.ResolveValueAtVersion(segment[i], m_sequence);
                    if (value == null)
                    {
                        continue;
                    }
                    Key *key = (Key *)segment[i];                    //.ToPointer();

                    Contract.Assert(key != null && key->Size <= MemoryDatabaseHandler.MAX_KEY_SIZE);

                    // Key Size
                    uint size = key->Size;
                    m_writer.WriteVarint32(size);
                    m_writer.WriteBytesUnsafe(&(key->Data), (int)size);

                    // Value

                    m_writer.WriteVarint64(value->Sequence);                     // sequence
                    size = value->Size;
                    if (size == 0)
                    {                     // empty key
                        m_writer.WriteByte(0);
                    }
                    else
                    {
                        m_writer.WriteVarint32(size);                         // value size
                        m_writer.WriteBytesUnsafe(&(value->Data), (int)size); // value data
                    }
#endif
                }

                if (m_writer.Position >= SnapshotFormat.FLUSH_SIZE)
                {
                    //Console.WriteLine("> partial flush (" + writer.Position + ")");
                    int written = await m_file.WriteCompletePagesAsync(m_writer.Buffer, m_writer.Position, ct).ConfigureAwait(false);

                    if (written > 0)
                    {
                        m_writer.Flush(written);
                    }
                }
            }

            m_writer.WriteFixed32(uint.MaxValue);

            //TODO: CRC? (would need to be computed on the fly, because we don't have the full slice in memory probably)
            m_writer.WriteFixed32(0);

            var levelEnd = checked (m_file.Length + (uint)m_writer.Position);
            m_jumpTable[level] = new KeyValuePair <ulong, ulong>(levelStart, levelEnd - levelStart);
            //Console.WriteLine("## level " + level + " ends at " + levelEnd);

            // optional padding to fill the rest of the page
            PadPageIfNeeded(SnapshotFormat.PAGE_SIZE, (byte)(0xFC - level));
        }