Example #1
0
        /// <summary>
        /// Retrieve metadata for a given object.
        /// DedupeObjectMap objects returned should be ordered in ascending order based on the chunk's position or address.
        /// </summary>
        /// <param name="key">Object key.</param>
        /// <returns>Object metadata.</returns>
        public override DedupeObject GetObjectMetadata(string key)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            key = DedupeCommon.SanitizeString(key);

            DbExpression e = new DbExpression(
                _ORM.GetColumnName <DedupeObject>(nameof(DedupeObject.Key)),
                DbOperators.Equals,
                key);

            DedupeObject ret = _ORM.SelectFirst <DedupeObject>(e);

            if (ret != null)
            {
                ret.Chunks    = GetChunks(key);
                ret.ObjectMap = GetObjectMap(key);

                if (ret.ObjectMap != null && ret.ObjectMap.Count > 0)
                {
                    ret.ObjectMap = ret.ObjectMap.OrderBy(o => o.ChunkAddress).ToList();
                }
            }

            return(ret);
        }
Example #2
0
        /// <summary>
        /// Add a configuration key-value pair.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="val">The value.</param>
        public override void AddConfigData(string key, string val)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (String.IsNullOrEmpty(val))
            {
                throw new ArgumentNullException(nameof(val));
            }

            key = DedupeCommon.SanitizeString(key);
            val = DedupeCommon.SanitizeString(val);

            string    keyCheckQuery = "SELECT * FROM DedupeConfig WHERE Key = '" + key + "'";
            DataTable keyCheckResult;

            string    keyDeleteQuery = "DELETE FROM DedupeConfig WHERE Key = '" + key + "'";
            DataTable keyDeleteResult;

            string    keyInsertQuery = "INSERT INTO DedupeConfig (Key, Val) VALUES ('" + key + "', '" + val + "')";
            DataTable keyInsertResult;

            lock (_ConfigLock)
            {
                if (Query(keyCheckQuery, out keyCheckResult))
                {
                    Query(keyDeleteQuery, out keyDeleteResult);
                }

                Query(keyInsertQuery, out keyInsertResult);
            }

            return;
        }
Example #3
0
        /// <summary>
        /// Increment reference count for a chunk by its key.  If the chunk does not exist, it is created.
        /// </summary>
        /// <param name="chunkKey">Chunk key.</param>
        /// <param name="length">The chunk length, used when creating the chunk.</param>
        public override void IncrementChunkRefcount(string chunkKey, int length)
        {
            if (String.IsNullOrEmpty(chunkKey))
            {
                throw new ArgumentNullException(nameof(chunkKey));
            }

            chunkKey = DedupeCommon.SanitizeString(chunkKey);

            lock (_ChunkLock)
            {
                DedupeChunk chunk = GetChunkMetadata(chunkKey);

                if (chunk != null)
                {
                    chunk.RefCount = chunk.RefCount + 1;
                    _ORM.Update <DedupeChunk>(chunk);
                }
                else
                {
                    chunk = new DedupeChunk(chunkKey, length, 1);
                    _ORM.Insert <DedupeChunk>(chunk);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Retrieve metadata for a given object.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <param name="metadata">Object metadata.</param>
        /// <returns>True if successful.</returns>
        public override bool GetObjectMetadata(string name, out ObjectMetadata metadata)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            name     = DedupeCommon.SanitizeString(name);
            metadata = null;

            string    query = "SELECT * FROM ObjectMap WHERE Name = '" + name + "'";
            DataTable result;
            bool      success = false;

            lock (_ObjectLock)
            {
                success = Query(query, out result);
            }

            if (result == null || result.Rows.Count < 1)
            {
                return(false);
            }
            if (!success)
            {
                return(false);
            }

            metadata = ObjectMetadata.FromDataTable(result);
            return(true);
        }
Example #5
0
        public override bool GetConfigData(string key, out string val)
        {
            val = null;

            key = DedupeCommon.SanitizeString(key);

            string    keyQuery = "SELECT configval FROM DedupeConfig WHERE configkey = '" + key + "' LIMIT 1";
            DataTable result;

            lock (_ConfigLock)
            {
                result = _Database.Query(keyQuery);
                if (result != null && result.Rows.Count > 0)
                {
                    foreach (DataRow curr in result.Rows)
                    {
                        val = curr["configval"].ToString();
                        if (_Debug)
                        {
                            Console.WriteLine("Returning " + key + ": " + val);
                        }
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #6
0
        /// <summary>
        /// Determine if a chunk exists in the index.
        /// </summary>
        /// <param name="key">Chunk key.</param>
        /// <returns>True if the chunk exists.</returns>
        public override bool ChunkExists(string key)
        {
            if (String.IsNullOrEmpty(key))
            {
                return(false);
            }

            key = DedupeCommon.SanitizeString(key);

            string    query = "SELECT * FROM ObjectMap WHERE ChunkKey = '" + key + "' LIMIT 1";
            DataTable result;

            lock (_ObjectLock)
            {
                if (Query(query, out result))
                {
                    if (result != null && result.Rows.Count > 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #7
0
        /// <summary>
        /// Determine if an object exists in the index.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <returns>True if the object exists.</returns>
        public override bool ObjectExists(string name)
        {
            if (String.IsNullOrEmpty(name))
            {
                return(false);
            }

            name = DedupeCommon.SanitizeString(name);

            string    query = "SELECT * FROM ObjectMap WHERE Name = '" + name + "' LIMIT 1";
            DataTable result;

            lock (_ObjectLock)
            {
                if (Query(query, out result))
                {
                    if (result != null && result.Rows.Count > 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #8
0
        /// <summary>
        /// Retrieve chunk metadata for a given object.
        /// </summary>
        /// <param name="key">Object key.</param>
        /// <returns>Chunks associated with the object.</returns>
        public override List <DedupeChunk> GetChunks(string key)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            List <DedupeChunk> ret = new List <DedupeChunk>();

            key = DedupeCommon.SanitizeString(key);
            List <DedupeObjectMap> maps = GetObjectMap(key);

            if (maps == null || maps.Count < 1)
            {
                return(ret);
            }

            List <string> chunkKeys = maps.Select(m => m.ChunkKey).ToList();

            if (chunkKeys == null || chunkKeys.Count < 1)
            {
                return(ret);
            }

            chunkKeys = chunkKeys.Distinct().ToList();

            DbExpression e = new DbExpression(
                _ORM.GetColumnName <DedupeChunk>(nameof(DedupeChunk.Key)),
                DbOperators.In,
                chunkKeys);

            ret = _ORM.SelectMany <DedupeChunk>(e);
            return(ret);
        }
Example #9
0
        /// <summary>
        /// Retrieve a configuration value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="val">The value.</param>
        /// <returns>True if successful.</returns>
        public override bool GetConfigData(string key, out string val)
        {
            val = null;
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            key = DedupeCommon.SanitizeString(key);

            string    keyQuery = "SELECT Val FROM DedupeConfig WHERE Key = '" + key + "' LIMIT 1";
            DataTable result;

            lock (_ConfigLock)
            {
                if (Query(keyQuery, out result))
                {
                    if (result != null && result.Rows.Count > 0)
                    {
                        foreach (DataRow curr in result.Rows)
                        {
                            val = curr["Val"].ToString();
                            if (_Debug)
                            {
                                Console.WriteLine("Returning " + key + ": " + val);
                            }
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Example #10
0
        public override void DeleteObjectChunks(string name, out List <string> garbageCollectChunks)
        {
            garbageCollectChunks = new List <string>();

            name = DedupeCommon.SanitizeString(name);

            string    selectQuery          = "SELECT * FROM ObjectMap WHERE Name = '" + name + "'";
            string    deleteObjectMapQuery = "DELETE FROM ObjectMap WHERE Name = '" + name + "'";
            DataTable result;
            bool      garbageCollect = false;

            lock (_ObjectLock)
            {
                result = _Database.Query(selectQuery);
                if (result == null || result.Rows.Count < 1)
                {
                    return;
                }

                foreach (DataRow curr in result.Rows)
                {
                    Chunk c = Chunk.FromDataRow(curr);
                    DecrementChunkRefcount(c.Key, out garbageCollect);
                    if (garbageCollect)
                    {
                        garbageCollectChunks.Add(c.Key);
                    }
                }

                result = _Database.Query(deleteObjectMapQuery);
            }
        }
Example #11
0
        /// <summary>
        /// Retrieve chunk metadata for a given object.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <param name="chunks">Chunks associated with the object.</param>
        /// <returns>True if successful.</returns>
        public override bool GetObjectChunks(string name, out List <Chunk> chunks)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            name   = DedupeCommon.SanitizeString(name);
            chunks = new List <Chunk>();

            string    query = "SELECT * FROM ObjectMap WHERE Name = '" + name + "'";
            DataTable result;
            bool      success = false;

            lock (_ObjectLock)
            {
                success = Query(query, out result);
            }

            if (result == null || result.Rows.Count < 1)
            {
                return(false);
            }
            if (!success)
            {
                return(false);
            }

            foreach (DataRow row in result.Rows)
            {
                chunks.Add(Chunk.FromDataRow(row));
            }

            return(true);
        }
Example #12
0
        public override bool AddObjectChunk(string name, long totalLen, Chunk chunk)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (totalLen < 1)
            {
                throw new ArgumentException("Total length must be greater than zero.");
            }
            if (chunk == null)
            {
                throw new ArgumentNullException(nameof(chunk));
            }

            name = DedupeCommon.SanitizeString(name);

            DataTable result = null;
            string    query  = AddObjectChunkQuery(name, totalLen, chunk);

            lock (_ObjectLock)
            {
                result = _Database.Query(query);
                return(IncrementChunkRefcount(chunk.Key, chunk.Length));
            }
        }
Example #13
0
        public override bool GetObjectChunks(string name, out List <Chunk> chunks)
        {
            name   = DedupeCommon.SanitizeString(name);
            chunks = new List <Chunk>();

            string    query = "SELECT * FROM ObjectMap WHERE Name = '" + name + "'";
            DataTable result;

            lock (_ObjectLock)
            {
                result = _Database.Query(query);
            }

            if (result == null || result.Rows.Count < 1)
            {
                return(false);
            }

            foreach (DataRow row in result.Rows)
            {
                chunks.Add(Chunk.FromDataRow(row));
            }

            return(true);
        }
Example #14
0
        public override bool AddObjectChunks(string name, long totalLen, List <Chunk> chunks)
        {
            name = DedupeCommon.SanitizeString(name);

            if (ObjectExists(name))
            {
                return(false);
            }

            DataTable     result;
            List <string> addObjectChunksQueries = BatchAddObjectChunksQuery(name, totalLen, chunks);

            lock (_ObjectLock)
            {
                foreach (string query in addObjectChunksQueries)
                {
                    result = _Database.Query(query);
                }

                foreach (Chunk currChunk in chunks)
                {
                    IncrementChunkRefcount(currChunk.Key, currChunk.Length);
                }
            }

            return(true);
        }
Example #15
0
        /// <summary>
        /// Add a configuration key-value pair.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="val">The value.</param>
        public override void AddConfigValue(string key, string val)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (String.IsNullOrEmpty(val))
            {
                throw new ArgumentNullException(nameof(val));
            }

            key = DedupeCommon.SanitizeString(key);
            val = DedupeCommon.SanitizeString(val);

            DbExpression e = new DbExpression(
                _ORM.GetColumnName <DedupeConfig>(nameof(DedupeConfig.Key)),
                DbOperators.Equals,
                key);

            DedupeConfig config = _ORM.SelectFirst <DedupeConfig>(e);

            if (config != null)
            {
                _ORM.Delete <DedupeConfig>(config);
            }

            config = new DedupeConfig(key, val);
            config = _ORM.Insert <DedupeConfig>(config);
        }
Example #16
0
        /// <summary>
        /// Decrement the reference count of a chunk by its key.  If the reference count reaches zero, the chunk is deleted.
        /// </summary>
        /// <param name="chunkKey">Chunk key.</param>
        /// <returns>Boolean indicating if the chunk should be garbage collected.</returns>
        public override bool DecrementChunkRefcount(string chunkKey)
        {
            if (String.IsNullOrEmpty(chunkKey))
            {
                throw new ArgumentNullException(nameof(chunkKey));
            }

            chunkKey = DedupeCommon.SanitizeString(chunkKey);

            DedupeChunk chunk = GetChunkMetadata(chunkKey);

            if (chunk == null)
            {
                return(false);
            }

            chunk.RefCount = chunk.RefCount - 1;
            if (chunk.RefCount < 1)
            {
                _ORM.Delete <DedupeChunk>(chunk);
                return(true);
            }
            else
            {
                _ORM.Update <DedupeChunk>(chunk);
                return(false);
            }
        }
Example #17
0
        /// <summary>
        /// Retrieve chunks containing data within a range of bytes from the original object.
        /// </summary>
        /// <param name="name">Object name.</param>
        /// <param name="start">Starting range.</param>
        /// <param name="end">Ending range.</param>
        /// <param name="chunks">Chunks.</param>
        /// <returns>True if successful.</returns>
        public override bool GetChunksForRange(string name, long start, long end, out List <Chunk> chunks)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (start < 0)
            {
                throw new ArgumentOutOfRangeException("Start of range must be zero or greater.");
            }
            if (end < 0)
            {
                throw new ArgumentOutOfRangeException("End of range must be zero or greater.");
            }
            if (end < start)
            {
                throw new ArgumentOutOfRangeException("End of range must be greater than or equal to start of range.");
            }

            name   = DedupeCommon.SanitizeString(name);
            chunks = new List <Chunk>();

            string query =
                "SELECT * FROM ObjectMap " +
                "WHERE Name = '" + name + "' AND " +
                "(" +
                "     (chunkAddress <= " + start + " AND chunkAddress + chunkLength > " + start + ") " +
                "  OR (chunkAddress <= " + end + " AND chunkAddress + chunkLength > " + end + ") " +
                "  OR (chunkAddress >= " + start + " AND chunkAddress <= " + end + ") " +
                ")";

            DataTable result;
            bool      success = false;

            lock (_ObjectLock)
            {
                success = Query(query, out result);
            }

            if (result == null || result.Rows.Count < 1)
            {
                return(false);
            }
            if (!success)
            {
                return(false);
            }

            foreach (DataRow row in result.Rows)
            {
                chunks.Add(Chunk.FromDataRow(row));
            }

            chunks = chunks.OrderBy(c => c.Address).ToList();
            return(true);
        }
Example #18
0
        /// <summary>
        /// Increment the reference count of a chunk key, or insert the key.
        /// </summary>
        /// <param name="key">The chunk key.</param>
        /// <param name="len">The length of the chunk.</param>
        /// <returns>True if successful.</returns>
        public override bool IncrementChunkRefcount(string key, long len)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            key = DedupeCommon.SanitizeString(key);

            string selectQuery = "";
            string updateQuery = "";
            string insertQuery = "";

            DataTable selectResult;
            DataTable updateResult;
            DataTable insertResult;

            selectQuery = "SELECT * FROM ChunkRefcount WHERE ChunkKey = '" + key + "'";
            insertQuery = "INSERT INTO ChunkRefcount (ChunkKey, ChunkLength, RefCount) VALUES ('" + key + "', '" + len + "', 1)";

            lock (_ChunkRefcountLock)
            {
                if (Query(selectQuery, out selectResult))
                {
                    if (selectResult == null || selectResult.Rows.Count < 1)
                    {
                        #region New-Entry

                        return(Query(insertQuery, out insertResult));

                        #endregion
                    }
                    else
                    {
                        #region Update

                        int currCount = 0;
                        foreach (DataRow curr in selectResult.Rows)
                        {
                            currCount = Convert.ToInt32(curr["RefCount"]);
                        }

                        currCount++;

                        updateQuery = "UPDATE ChunkRefcount SET RefCount = '" + currCount + "' WHERE ChunkKey = '" + key + "'";
                        return(Query(updateQuery, out updateResult));

                        #endregion
                    }
                }
                else
                {
                    return(false);
                }
            }
        }
Example #19
0
        /// <summary>
        /// Decrement the reference count of a chunk key, or delete the key.
        /// </summary>
        /// <param name="key">The chunk key.</param>
        /// <param name="garbageCollect">Boolean indicating if the chunk should be garbage collected.</param>
        /// <returns>True if successful.</returns>
        public override bool DecrementChunkRefcount(string key, out bool garbageCollect)
        {
            garbageCollect = false;
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            key = DedupeCommon.SanitizeString(key);

            string selectQuery = "";
            string updateQuery = "";
            string deleteQuery = "";

            DataTable selectResult;
            DataTable updateResult;
            DataTable deleteResult;

            selectQuery = "SELECT * FROM ChunkRefcount WHERE ChunkKey = '" + key + "'";
            deleteQuery = "DELETE FROM ChunkRefcount WHERE ChunkKey = '" + key + "'";

            lock (_ChunkRefcountLock)
            {
                if (Query(selectQuery, out selectResult))
                {
                    if (selectResult == null || selectResult.Rows.Count < 1)
                    {
                        return(false);
                    }
                    else
                    {
                        int currCount = 0;
                        foreach (DataRow curr in selectResult.Rows)
                        {
                            currCount = Convert.ToInt32(curr["RefCount"]);
                        }

                        currCount--;
                        if (currCount == 0)
                        {
                            garbageCollect = true;
                            return(Query(deleteQuery, out deleteResult));
                        }
                        else
                        {
                            updateQuery = "UPDATE ChunkRefcount SET RefCount = '" + currCount + "' WHERE ChunkKey = '" + key + "'";
                            return(Query(updateQuery, out updateResult));
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }
        }
Example #20
0
        /// <summary>
        /// Add chunks from an object to the index.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <param name="totalLen">The total length of the object.</param>
        /// <param name="chunks">The chunks from the object.</param>
        /// <returns>True if successful.</returns>
        public override bool AddObjectChunks(string name, long totalLen, List <Chunk> chunks)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (totalLen < 1)
            {
                throw new ArgumentException("Total length must be greater than zero.");
            }
            if (chunks == null || chunks.Count < 1)
            {
                throw new ArgumentException("No chunk data supplied.");
            }

            name = DedupeCommon.SanitizeString(name);

            if (ObjectExists(name))
            {
                return(false);
            }

            DataTable     result;
            List <string> addObjectChunksQueries = BatchAddObjectChunksQuery(name, totalLen, chunks);

            lock (_ObjectLock)
            {
                foreach (string query in addObjectChunksQueries)
                {
                    if (!Query(query, out result))
                    {
                        if (_Debug)
                        {
                            Console.WriteLine("Insert query failed: " + query);
                        }
                        return(false);
                    }
                }

                foreach (Chunk currChunk in chunks)
                {
                    if (!IncrementChunkRefcount(currChunk.Key, currChunk.Length))
                    {
                        if (_Debug)
                        {
                            Console.WriteLine("Unable to increment refcount for chunk: " + currChunk.Key);
                        }
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #21
0
        /// <summary>
        /// Delete an object and dereference the associated chunks.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <param name="garbageCollectChunks">List of chunk keys that should be garbage collected.</param>
        public override void DeleteObjectChunks(string name, out List <string> garbageCollectChunks)
        {
            garbageCollectChunks = new List <string>();
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            name = DedupeCommon.SanitizeString(name);

            string    selectQuery          = "SELECT * FROM ObjectMap WHERE Name = '" + name + "'";
            string    deleteObjectMapQuery = "DELETE FROM ObjectMap WHERE Name = '" + name + "'";
            DataTable result;
            bool      garbageCollect = false;

            lock (_ObjectLock)
            {
                if (!Query(selectQuery, out result))
                {
                    if (_Debug)
                    {
                        Console.WriteLine("Unable to retrieve object map for object: " + name);
                    }
                }

                if (result == null || result.Rows.Count < 1)
                {
                    return;
                }

                foreach (DataRow curr in result.Rows)
                {
                    Chunk c = Chunk.FromDataRow(curr);
                    DecrementChunkRefcount(c.Key, out garbageCollect);
                    if (garbageCollect)
                    {
                        garbageCollectChunks.Add(c.Key);
                    }
                }

                if (!Query(deleteObjectMapQuery, out result))
                {
                    if (_Debug)
                    {
                        Console.WriteLine("Unable to delete object map entries for object: " + name);
                    }
                }
            }
        }
Example #22
0
        public override bool DecrementChunkRefcount(string key, out bool garbageCollect)
        {
            garbageCollect = false;

            key = DedupeCommon.SanitizeString(key);

            string selectQuery = "";
            string updateQuery = "";
            string deleteQuery = "";

            DataTable selectResult;
            DataTable updateResult;
            DataTable deleteResult;

            selectQuery = "SELECT * FROM ChunkRefcount WHERE ChunkKey = '" + key + "'";
            deleteQuery = "DELETE FROM ChunkRefcount WHERE ChunkKey = '" + key + "'";

            lock (_ChunkRefcountLock)
            {
                selectResult = _Database.Query(selectQuery);
                if (selectResult == null || selectResult.Rows.Count < 1)
                {
                    return(false);
                }
                else
                {
                    int currCount = 0;
                    foreach (DataRow curr in selectResult.Rows)
                    {
                        currCount = Convert.ToInt32(curr["RefCount"]);
                    }

                    currCount--;
                    if (currCount == 0)
                    {
                        garbageCollect = true;
                        deleteResult   = _Database.Query(deleteQuery);
                        return(true);
                    }
                    else
                    {
                        updateQuery  = "UPDATE ChunkRefcount SET RefCount = '" + currCount + "' WHERE ChunkKey = '" + key + "'";
                        updateResult = _Database.Query(updateQuery);
                        return(true);
                    }
                }
            }
        }
Example #23
0
        /// <summary>
        /// Determine if an object exists in the index.
        /// </summary>
        /// <param name="key">Object key.</param>
        /// <returns>True if the object exists.</returns>
        public override bool Exists(string key)
        {
            if (String.IsNullOrEmpty(key))
            {
                return(false);
            }

            key = DedupeCommon.SanitizeString(key);

            DbExpression e = new DbExpression(
                _ORM.GetColumnName <DedupeObject>(nameof(DedupeObject.Key)),
                DbOperators.Equals,
                key);

            return(_ORM.Exists <DedupeObject>(e));
        }
Example #24
0
        /// <summary>
        /// Retrieve metadata for a given chunk by its key.
        /// </summary>
        /// <param name="chunkKey">Chunk key.</param>
        /// <returns>Chunk metadata.</returns>
        public override DedupeChunk GetChunkMetadata(string chunkKey)
        {
            if (String.IsNullOrEmpty(chunkKey))
            {
                throw new ArgumentNullException(nameof(chunkKey));
            }

            chunkKey = DedupeCommon.SanitizeString(chunkKey);

            DbExpression e = new DbExpression(
                _ORM.GetColumnName <DedupeChunk>(nameof(DedupeChunk.Key)),
                DbOperators.Equals,
                chunkKey);

            DedupeChunk ret = _ORM.SelectFirst <DedupeChunk>(e);

            return(ret);
        }
Example #25
0
        public override bool ObjectExists(string name)
        {
            name = DedupeCommon.SanitizeString(name);

            string    query = "SELECT * FROM ObjectMap WHERE Name = '" + name + "' LIMIT 1";
            DataTable result;

            lock (_ObjectLock)
            {
                result = _Database.Query(query);
                if (result != null && result.Rows.Count > 0)
                {
                    return(true);
                }
            }

            return(false);
        }
Example #26
0
        /// <summary>
        /// Add a new object to the index.
        /// </summary>
        /// <param name="key">Object key.</param>
        /// <param name="length">The total length of the object.</param>
        public override void AddObject(string key, long length)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (length < 1)
            {
                throw new ArgumentException("Length must be greater than zero.");
            }

            key = DedupeCommon.SanitizeString(key);
            if (Exists(key))
            {
                throw new ArgumentException("An object with key '" + key + "' already exists.");
            }

            DedupeObject obj = _ORM.Insert <DedupeObject>(new DedupeObject(key, length));
        }
Example #27
0
        /// <summary>
        /// Add chunk from an object to the index.
        /// </summary>
        /// <param name="name">The name of the object.</param>
        /// <param name="totalLen">The total length of the object.</param>
        /// <param name="chunk">Chunk from the object..</param>
        /// <returns>True if successful.</returns>
        public override bool AddObjectChunk(string name, long totalLen, Chunk chunk)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (totalLen < 1)
            {
                throw new ArgumentException("Total length must be greater than zero.");
            }
            if (chunk == null)
            {
                throw new ArgumentNullException(nameof(chunk));
            }

            name = DedupeCommon.SanitizeString(name);

            DataTable result = null;
            string    query  = AddObjectChunkQuery(name, totalLen, chunk);

            lock (_ObjectLock)
            {
                if (!Query(query, out result))
                {
                    if (_Debug)
                    {
                        Console.WriteLine("Insert query failed: " + query);
                    }
                    return(false);
                }

                if (!IncrementChunkRefcount(chunk.Key, chunk.Length))
                {
                    if (_Debug)
                    {
                        Console.WriteLine("Unable to increment refcount for chunk: " + chunk.Key);
                    }
                    return(false);
                }
            }

            return(true);
        }
Example #28
0
        /// <summary>
        /// Retrieve the object map containing the metadata for a given address within the original object.
        /// </summary>
        /// <param name="key">Object key.</param>
        /// <param name="position">Starting byte position.</param>
        /// <returns>Dedupe object map.</returns>
        public override DedupeObjectMap GetObjectMapForPosition(string key, long position)
        {
            if (String.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (position < 0)
            {
                throw new ArgumentOutOfRangeException("Start of range must be zero or greater.");
            }

            key = DedupeCommon.SanitizeString(key);

            DedupeObject obj = GetObjectMetadata(key);

            if (obj == null)
            {
                return(null);
            }

            string objMapTable  = _ORM.GetTableName(typeof(DedupeObjectMap));
            string objKeyCol    = _ORM.GetColumnName <DedupeObjectMap>(nameof(DedupeObjectMap.ObjectKey));
            string chunkAddrCol = _ORM.GetColumnName <DedupeObjectMap>(nameof(DedupeObjectMap.ChunkAddress));
            string chunkLenCol  = _ORM.GetColumnName <DedupeObjectMap>(nameof(DedupeObjectMap.ChunkLength));

            string query =
                "SELECT * FROM " + objMapTable + " " +
                "WHERE " +
                "  " + objKeyCol + " = '" + obj.Key + "' " +
                "  AND " + chunkAddrCol + " <= " + position + " AND " + chunkAddrCol + " + " + chunkLenCol + " > " + position + " ";

            DedupeObjectMap map    = null;
            DataTable       result = _ORM.Query(query);

            if (result != null && result.Rows.Count > 0)
            {
                map = _ORM.DataRowToObject <DedupeObjectMap>(result.Rows[0]);
            }

            return(map);
        }
Example #29
0
        public override bool GetObjectMetadata(string name, out ObjectMetadata metadata)
        {
            name     = DedupeCommon.SanitizeString(name);
            metadata = null;

            string    query = "SELECT * FROM ObjectMap WHERE Name = '" + name + "'";
            DataTable result;

            lock (_ObjectLock)
            {
                result = _Database.Query(query);
            }

            if (result == null || result.Rows.Count < 1)
            {
                return(false);
            }

            metadata = ObjectMetadata.FromDataTable(result);
            return(true);
        }
Example #30
0
        /// <summary>
        /// Retrieve the chunk containing data for a given address within the original object.
        /// </summary>
        /// <param name="name">Object name.</param>
        /// <param name="start">Starting range.</param>
        /// <param name="chunk">Chunk.</param>
        /// <returns>True if successful.</returns>
        public override bool GetChunkForPosition(string name, long start, out Chunk chunk)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (start < 0)
            {
                throw new ArgumentOutOfRangeException("Start of range must be zero or greater.");
            }

            chunk = null;
            name  = DedupeCommon.SanitizeString(name);

            string query =
                "SELECT * FROM ObjectMap " +
                "WHERE " +
                "  Name = '" + name + "' " +
                "  AND chunkAddress <= " + start + " AND chunkAddress + chunkLength > " + start + " ";

            DataTable result;
            bool      success = false;

            lock (_ObjectLock)
            {
                success = Query(query, out result);
            }

            if (result == null || result.Rows.Count < 1)
            {
                return(false);
            }
            if (!success)
            {
                return(false);
            }

            chunk = Chunk.FromDataRow(result.Rows[0]);
            return(true);
        }