コード例 #1
0
        /// <summary>
        /// Register the chunks in the given file to the DB.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="chunks">The chunks.</param>
        public void AddChunks(string filePath, int[] chunks)
        {
            logger.DebugFormat("Adding chunks {0} for file {1}.",
                               string.Join(",", System.Array.ConvertAll <int, string>(chunks,
                                                                                      x => x.ToString())), filePath);
            var txnProvider = new NHTransactionProvider(
                new NHSessionProvider(_sessionFactory));

            using (txnProvider) {
                using (var transaction = txnProvider.BeginTransaction()) {
                    var helper = new ChunkDbHelper(
                        txnProvider.SessionProvider.CurrentSession);
                    ManagedFile file            = helper.GetManagedFile(filePath);
                    var         chunkMap        = file.ChunkMap;
                    int         numAlreadyExist = 0;
                    foreach (var chunkIndex in chunks)
                    {
                        byte[] hash  = chunkMap.HashAt(chunkIndex);
                        var    entry = new DataChunk {
                            File       = file,
                            ChunkIndex = chunkIndex,
                            Hash       = hash,
                            Count      = 0
                        };
                        bool added = helper.AddChunkIfNotExists(entry);
                        if (!added)
                        {
                            numAlreadyExist++;
                        }
                    }
                    transaction.Commit();
                    logger.DebugFormat(
                        "Chunks added. {0} out of {1} chunks already exist.",
                        numAlreadyExist, chunks.Length);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Adds a file to the Chunk DB.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="forEachChunk">(index, hash)</param>
        /// <param name="forEofChunk">(index, chunk size)</param>
        void AddFileAllChunks(string filePath, Action <int, byte[]> forEachChunk, Action <int, int> forEofChunk)
        {
            var txnProvider = new NHTransactionProvider(
                new NHSessionProvider(_sessionFactory));

            var         session = txnProvider.SessionProvider.CurrentSession;
            ManagedFile file;

            // In a stateful session.
            using (txnProvider) {
                using (var transaction = txnProvider.BeginTransaction()) {
                    var helper = new ChunkDbHelper(session);
                    file = helper.CreateManagedFileFromLocalFile(filePath);
                    // Have the file committed to DB.
                    transaction.Commit();
                }
            }

            // Choose stateless session for bulk insert.
            var statelessSession = _sessionFactory.OpenStatelessSession();

            using (var transaction = statelessSession.BeginTransaction()) {
                SHA1 sha = new SHA1CryptoServiceProvider();
                using (var stream = File.OpenRead(filePath)) {
                    int  chunkIndex = 0;
                    var  chunk      = new byte[DataChunk.ChunkSize];
                    int  duplicates = 0;
                    bool isEofChunk = false;
                    for (; ; chunkIndex++)
                    {
                        long offset     = stream.Position;
                        int  readLength = stream.Read(chunk, 0, chunk.Length);

                        if (readLength == 0)
                        {
                            if (forEofChunk != null)
                            {
                                forEofChunk(chunkIndex - 1, DataChunk.ChunkSize);
                            }
                            break;
                        }

                        if (readLength < DataChunk.ChunkSize)
                        {
                            // Last chunk.
                            isEofChunk = true;
                            // The rest of the buffer is padded with 0s.
                            System.Array.Clear(chunk, readLength,
                                               chunk.Length - readLength);
                            if (forEofChunk != null)
                            {
                                forEofChunk(chunkIndex, readLength);
                            }
                        }

                        // Hash is computed over the full chunk buffer with
                        // padding in case of a small chunk.
                        byte[] hash = sha.ComputeHash(chunk);

                        if (forEachChunk != null)
                        {
                            forEachChunk(chunkIndex, hash);
                        }

                        bool alreadyExists = ChunkDbHelper.AddChunkIfNotExists(statelessSession,
                                                                               new DataChunk {
                            Hash       = hash,
                            File       = file,
                            ChunkIndex = chunkIndex,
                            Count      = 0
                        });
                        if (alreadyExists)
                        {
                            duplicates++;
                        }

                        if (isEofChunk)
                        {
                            break;
                        }
                    }
                    transaction.Commit();
                    logger.DebugFormat("File {0} added to ChunkDb.", filePath);
                    logger.DebugFormat("Number of duplicates {0}", duplicates);
                }
            }
        }