Esempio n. 1
0
        public long WriteDocument(DocumentId documentId, byte[] blob)
        {
            // calculate the size of the document including meta data
            int size = 2 + documentId.Length + 4 + blob.Length;

            int position = 0;

            Buffer.BlockCopy(BitConverter.GetBytes((UInt16)documentId.Length), 0, m_writeDocumentBuffer, position, 2);
            position += 2;

            Buffer.BlockCopy(documentId.Bytes, 0, m_writeDocumentBuffer, position, documentId.Length);
            position += documentId.Length;

            Buffer.BlockCopy(BitConverter.GetBytes(blob.Length), 0, m_writeDocumentBuffer, position, 4);
            position += 4;

            if (blob.Length > 0)
            {
                Buffer.BlockCopy(blob, 0, m_writeDocumentBuffer, position, blob.Length);
            }

            m_writerStream.Write(m_writeDocumentBuffer, 0, size);

            return m_writerStream.Position - blob.Length;
        }
Esempio n. 2
0
        public Document GetDocument(DocumentId documentId)
        {
            Document document;

            m_documents.TryGetValue(documentId, out document);

            return document;
        }
Esempio n. 3
0
        protected bool Equals(DocumentId other)
        {
            if (other.Bytes.Length != Bytes.Length)
            {
                return false;
            }

            return Bytes.SequenceEqual(other.Bytes);
        }
        public void ThenDocumentIsInTheDatabaseWithKeyAndValue(int key, string value)
        {
            DocumentId documentId = new DocumentId(key);

            byte[] valueBytes = m_databaseContext.Database.Get(documentId);

            string dbValue = Encoding.ASCII.GetString(valueBytes);

            Assert.AreEqual(dbValue, value);
        }
Esempio n. 5
0
        public Document GetDocumentForUpdate(DocumentId documentId, int transactionId)
        {
            Document document;

            if (m_documents.TryGetValue(documentId, out document) && document.IsLocked && transactionId != document.TransactionId)
            {
                throw new DocumentLockedException();
            }
            else if (document != null && document.TransactionId == 0 && transactionId != -1)
            {
                document.TransactionLock(transactionId);
            }

            return document;
        }
Esempio n. 6
0
        public void ReadDocumentUpdatedByTransaction()
        {
            DocumentId id1 = new DocumentId("1");

            m_db.Update(id1, new byte[1] { 0 });

            int transactionId = m_db.StartTransaction();

            m_db.TransactionUpdate(transactionId, id1, new byte[1] { 1 });

            byte[] blob = m_db.TransactionGet(transactionId, id1);
            Assert.AreEqual(1, blob[0]);

            // reading without transaction should return uncommitted document
            blob = m_db.Get(id1);
            Assert.AreEqual(0, blob[0]);

            m_db.CommitTransaction(transactionId);

            // reading the object agian after the transaction committed making sure we are reading the new committed document
            blob = m_db.Get(id1);
            Assert.AreEqual(1, blob[0]);
        }
Esempio n. 7
0
        public void ReadOldRevisionDuringTransaction()
        {
            DocumentId id1 = new DocumentId("1");

            m_db.Update(id1, new byte[1] { 0 });

            int transactionId = m_db.StartTransaction();

            m_db.Update(id1, new byte[1] { 1 });

            byte[] blob = m_db.TransactionGet(transactionId, id1);

            Assert.AreEqual(0, blob[0]);

            m_db.CommitTransaction(transactionId);

            transactionId = m_db.StartTransaction();

            blob = m_db.TransactionGet(transactionId, id1);

            Assert.AreEqual(1, blob[0]);

            m_db.CommitTransaction(transactionId);
        }
Esempio n. 8
0
        public byte[] TransactionGet(int transactionId, DocumentId documentId)
        {
            Transaction transaction;

            if (!m_pendingTransaction.TryGetValue(transactionId, out transaction))
            {
                throw new TransactionNotExistException();
            }

            Document document = m_documentStore.GetDocument(documentId);
            if (document == null)
            {
                return ZeroBlob;
            }

            // if updated by current transaction we just return the current blob
            if (document.TransactionId == transactionId)
            {
                return transaction.GetBlob(documentId);
            }

            // we need to find the current revision
            DocumentRevision revision = document.GetDocumentRevisionByTimestamp(transaction.DBTimestamp);

            // if there is no revision the object is not exist for this timestamp
            if (revision == null)
            {
                return ZeroBlob;
            }

            return ReadInternal(revision.BlobFileLocation, revision.BlobSize);
        }
Esempio n. 9
0
        public Dictionary<DocumentId, Document> GetDocuments(out ulong dbTimestamp)
        {
            dbTimestamp = 0;

            Dictionary<DocumentId, Document> documents = new Dictionary<DocumentId, Document>();

            // initialize the buffers
            byte[] timestampBuffer = new byte[12];
            byte[] documentIdLengthBuffer = new byte[2];
            byte[] documentIdBuffer = new byte[UInt16.MaxValue];

            byte[] blobLengthBuffer = new byte[4];

            int numberOfDocuments = 0;
            int documentsCounter = 0;

            // now we read all the objects meta data (not loading any data yet)
            while (m_readStream.Position < m_readStream.Length)
            {
                if (numberOfDocuments == documentsCounter)
                {
                    // now we are reading the object timestamp
                    m_readStream.Read(timestampBuffer, 0, 12);
                    dbTimestamp = BitConverter.ToUInt64(timestampBuffer, 0);

                    numberOfDocuments = BitConverter.ToInt32(timestampBuffer, 8);
                    documentsCounter = 0;
                }

                // first is the object id lenth
                m_readStream.Read(documentIdLengthBuffer, 0, 2);
                UInt16 objectIdLength = BitConverter.ToUInt16(documentIdLengthBuffer, 0);

                // read the objectId
                m_readStream.Read(documentIdBuffer, 0, objectIdLength);

                byte[] documentIdBytes = new byte[objectIdLength];
                Buffer.BlockCopy(documentIdBuffer, 0, documentIdBytes, 0, objectIdLength);

                DocumentId documentId = new DocumentId(documentIdBytes);

                // read the blob length
                m_readStream.Read(blobLengthBuffer, 0, 4);
                int blobLength = BitConverter.ToInt32(blobLengthBuffer, 0);
                long blobLocation = m_readStream.Position;

                // take the position of the file to the next document
                m_readStream.Position += blobLength;

                // check if the document not exist and not deleted (zero length is deleted
                if (!documents.ContainsKey(documentId) && blobLength > 0)
                {
                    documents.Add(documentId, new Document(documentId, dbTimestamp, blobLocation, blobLength));
                }
                else
                {
                    // if the document is deleted we just remove the document from the store
                    if (blobLength == 0)
                    {
                        documents.Remove(documentId);
                    }
                    else
                    {
                        Document document = documents[documentId];

                        document.Update(dbTimestamp, blobLocation, blobLength, false);
                    }
                }

                documentsCounter++;
            }

            if (documentsCounter != numberOfDocuments)
            {
                // database is corrupted, need to recover
                throw new Exception("Database is corrupted");
            }

            return documents;
        }
Esempio n. 10
0
        private void TransactionUpdate()
        {
            byte[] transactionIdBytes = m_serverSocket.Receive();

            int transactionId = BitConverter.ToInt32(transactionIdBytes, 0);

            byte[] documentIdBytes = m_serverSocket.Receive();

            DocumentId documentId = new DocumentId(documentIdBytes);

            byte[] blob = m_serverSocket.Receive();

            try
            {
                m_db.TransactionUpdate(transactionId, documentId, blob);

                // sending success
                m_serverSocket.Send(Protocol.Success);
            }
            catch (TransactionNotExistException ex)
            {
                m_serverSocket.SendMore(Protocol.Failed).Send("Transaction doesn't exist");
            }
            catch (DocumentLockedException)
            {
                m_serverSocket.SendMore(Protocol.Failed).Send("Document locked by another transaction");
            }
        }
Esempio n. 11
0
 public byte[] GetBlob(DocumentId documentId)
 {
     return m_updates[documentId];
 }
Esempio n. 12
0
 public void AddUpdate(DocumentId documentId, byte[] blob)
 {
     m_updates.Add(documentId, blob);
 }
Esempio n. 13
0
        private void TransactionGet()
        {
            byte[] transactionIdBytes = m_serverSocket.Receive();

            int transactionId = BitConverter.ToInt32(transactionIdBytes, 0);

            byte[] documentIdBytes = m_serverSocket.Receive();

            DocumentId documentId = new DocumentId(documentIdBytes);

            try
            {
                byte [] blob = m_db.TransactionGet(transactionId, documentId);

                if (blob == null)
                {
                    blob = new byte[0];
                }

                m_serverSocket.SendMore(Protocol.Success).Send(blob);
            }
            catch (TransactionNotExistException ex)
            {
                m_serverSocket.SendMore(Protocol.Failed).Send("Transaction doesn't exist");
            }
        }
Esempio n. 14
0
        private void Delete()
        {
            byte[] documentIdBytes = m_serverSocket.Receive();

            DocumentId documentId = new DocumentId(documentIdBytes);

            try
            {
                m_db.Delete(documentId);

                // sending success
                m_serverSocket.Send(Protocol.Success);
            }
            catch (DocumentLockedException)
            {
                m_serverSocket.SendMore(Protocol.Failed).Send("Document locked by another transaction");
            }
        }
Esempio n. 15
0
 public void Delete(DocumentId documentId)
 {
     Update(documentId, ZeroBlob);
 }
Esempio n. 16
0
 public void TransactionDelete(int transactionId, DocumentId documentId)
 {
     TransactionUpdate(transactionId, documentId, ZeroBlob);
 }
Esempio n. 17
0
        public byte[] Get(DocumentId key)
        {
            Document document = m_documentStore.GetDocument(key);

            if (document != null)
            {
                return ReadInternal(document.CurrentRevision.BlobFileLocation, document.CurrentRevision.BlobSize);
            }
            else
            {
                return ZeroBlob;
            }
        }
Esempio n. 18
0
        public void TryReadFutureDocument()
        {
            int transactionId = m_db.StartTransaction();

            DocumentId id1 = new DocumentId("1");

            // this object is stored out of transaction therefore should be visible for the transaction
            m_db.Update(id1, new byte[1] { 0 });

            byte[] blob = m_db.TransactionGet(transactionId, id1);

            Assert.IsNull(blob);

            m_db.CommitTransaction(transactionId);
        }
Esempio n. 19
0
        public void TransactionUpdate(int transactionId, DocumentId documentId, byte[] blob)
        {
            Transaction transaction;

            if (!m_pendingTransaction.TryGetValue(transactionId, out transaction))
            {
                throw new TransactionNotExistException();
            }

            try
            {
                // mark the document is updated by transaction
                m_documentStore.GetDocumentForUpdate(documentId, transactionId);
            }
            catch (DocumentLockedException)
            {
                m_log.InfoFormat("Tranasction {1} update failed because document is locked by another transaction, documentId(bytes):{0}",
                    documentId.GetBytesReprestnation(), transactionId);

                throw;
            }

            transaction.AddUpdate(documentId, blob);
        }
Esempio n. 20
0
 public void AddNewDocument(DocumentId documentId, ulong documentTimeStamp, long blobFileLocation, int blobSize)
 {
     m_documents.Add(documentId, new Document(documentId, documentTimeStamp, blobFileLocation, blobSize));
 }
Esempio n. 21
0
        public void Update(DocumentId documentId, byte[] blob)
        {
            Document document;
            try
            {
                document = m_documentStore.GetDocumentForUpdate(documentId, -1);
            }
            catch (DocumentLockedException)
            {
                m_log.InfoFormat("Update failed because document is locked by another transaction, documentId(bytes):{0}",
                    documentId.GetBytesReprestnation());

                throw;
            }

            DBTimeStamp++;

            m_databaseFileWriter.BeginTimestamp(DBTimeStamp, 1);

            long documentLocation = m_databaseFileWriter.WriteDocument(documentId, blob);

            if (blob.Length > 0)
            {
                m_cacheProvider.Set(documentLocation, blob);
            }

            m_databaseFileWriter.Flush();

            if (document != null)
            {
                document.Update(DBTimeStamp, documentLocation, blob.Length, true);
            }
            else
            {
                m_documentStore.AddNewDocument(documentId, DBTimeStamp, documentLocation, blob.Length);
            }
        }
Esempio n. 22
0
        public Document(DocumentId documentId, ulong documentTimeStamp, long blobFileLocation, int blobSize)
        {
            DocumentId = documentId;

            CurrentRevision = new DocumentRevision(documentId,documentTimeStamp, blobFileLocation, blobSize);
        }
Esempio n. 23
0
        private void Get()
        {
            byte[] documentIdBytes = m_serverSocket.Receive();

            DocumentId documentId = new DocumentId(documentIdBytes);

            byte[] blob = m_db.Get(documentId);

            if (blob == null)
            {
                blob = new byte[0];
            }

            m_serverSocket.SendMore(Protocol.Success).Send(blob);
        }