Exemple #1
0
        /// <summary>
        /// Put with a size limit. Data larger than the limit will be splitted into
        /// pieces and put to different under different DHT keys.
        /// </summary>
        /// <param name="maxSize">The size limit</param>
        /// <param name="split">Whether to split the oversized data</param>
        /// <exception cref="ArgumentException">Data larger than the limit and
        /// split specified as false</exception>
        public bool Put(byte[] key, byte[] value, int ttl, int maxSize, bool split)
        {
            bool result;

            if (value.Length > maxSize)
            {
                if (split)
                {
                    BrunetDhtEntry    bde       = new BrunetDhtEntry(key, value, ttl);
                    FragmentationInfo frag_info = new FragmentationInfo(key);
                    frag_info.PieceLength = maxSize;
                    result = PutFragments(bde, frag_info);
                }
                else
                {
                    throw new ArgumentException("Data too large but split opted out.");
                }
            }
            else
            {
                result = _dht.Put(key, value, ttl);
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Gets the first data item of the given name and possibly gets the
        /// indicated pieces from DHT.
        /// </summary>
        /// <param name="getPieces">Whether to get pieces if the data at the
        /// specified DHT name is a FragmentationInfo</param>
        public DhtGetResult GetOneDatum(byte[] key, bool getPieces,
                                        OneDatumMode mode)
        {
            DhtGetResult[] results = _dht.Get(key);
            DhtGetResult   ret;

            if (results.Length == 0)
            {
                ret = null;
            }
            else
            {
                DhtGetResult dgr;
                if (mode == OneDatumMode.FirstOne)
                {
                    dgr = results[0];
                }
                else if (mode == OneDatumMode.LastOne)
                {
                    dgr = results[results.Length - 1];
                }
                else
                {
                    throw new NotImplementedException(
                              "This OneDatumMode not implemented.");
                }
                DictionaryData dd = null;
                try {
                    dd = DictionaryData.CreateDictionaryData(dgr.value);
                } catch (Exception ex) {
                    // Not an error in this case. Log with verbose level.
                    Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                       ex);
                }
                if (dd != null && dd is FragmentationInfo)
                {
                    FragmentationInfo frag_info = dd as FragmentationInfo;
                    BrunetDhtEntry    bde       = null;
                    try {
                        bde = GetFragments(frag_info) as BrunetDhtEntry;
                        RegularData rd = (RegularData)DictionaryData.CreateDictionaryData(
                            bde.Value);
                        //Only 1 entry (if any) in this array
                        ret = new DhtGetResult(rd.PayLoad, bde.Age, bde.Ttl);
                    } catch (Exception ex) {
                        Logger.WriteLineIf(LogLevel.Error, _log_props, string.Format("Can't get fragments."), ex);
                        ret = null;
                    }
                }
                else
                {
                    ret = dgr;
                }
            }
            return(ret);
        }
Exemple #3
0
        /// <exception cref="Exception">Operation Failed</exception>
        /// <returns>A BrunetDhtEntry that has the whole chunk of data</returns>
        public DictionaryData GetFragments(FragmentationInfo info, bool concurrently)
        {
            BrunetDhtEntry ret = null;

            byte[]   base_key  = info.BaseKey;
            int      piece_num = info.PieceNum;
            MemBlock fragments;
            int      largest_age;
            int      smallest_ttl;

            /*
             * @TODO: It doesn't have to be sequential but let's first get it work with
             * this approach
             */

#if FUSHARE_PF
            DateTime get_started = DateTime.UtcNow;
#endif
            if (!concurrently)
            {
                fragments = GetFragsSequentially(base_key, piece_num, out largest_age, out smallest_ttl);
            }
            else
            {
                //fragments = GetFragsConcurrently(base_key, piece_num, out largest_age, out smallest_ttl);
                fragments = GetFragsInBulk(base_key, piece_num, out largest_age, out smallest_ttl);
            }

#if FUSHARE_PF
            DateTime get_finished = DateTime.UtcNow;
            TimeSpan get_time     = get_finished - get_started;
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("Total time used to get {0}: {1} seconds",
                                             Encoding.UTF8.GetString(base_key), get_time));
#endif
            if (fragments != null)
            {
                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("Fragments successfully got from DHT"));

                //Got the fragments correctly
                ret = new BrunetDhtEntry(base_key, (new RegularData(fragments)).SerializeTo(),
                                         largest_age, smallest_ttl);
                return(ret);
            }
            else
            {
                Logger.WriteLineIf(LogLevel.Error, _log_props,
                                   string.Format("DHT Get of fragments failed"));
                throw new Exception("DHT Get of fragments failed.");
            }
        }
Exemple #4
0
        /// <summary>
        /// Puts fragments to Dht.
        /// </summary>
        /// <param name="bde">The data object.</param>
        /// <param name="fragInfo">Object that contains the meta info.</param>
        /// <param name="concurrently">Puts concurrently if set to true</param>
        /// <returns>True if the operation succeeds.</returns>
        public bool PutFragments(BrunetDhtEntry bde, FragmentationInfo fragInfo,
                                 bool concurrently)
        {
            byte[]   info_key     = bde.Key;
            int      ttl          = bde.Ttl; //This ttl is used by every piece and the frag info
            MemBlock data         = MemBlock.Reference(bde.Value);
            int      piece_length = 0;
            int      offset       = 0;
            IList <FingerprintedData> fragments = new List <FingerprintedData>();

            while (offset < data.Length)
            {
                piece_length = (offset + fragInfo.PieceLength > data.Length) ?
                               data.Length - offset : fragInfo.PieceLength;
                MemBlock piece = data.Slice(offset, piece_length);
                offset += piece_length;
                FingerprintedData fpd = new FingerprintedData(new RegularData(piece));
                fragments.Add(fpd);
            }

            //Update the piece number in fragInfo.
            Logger.WriteLineIf(LogLevel.Info, _log_props,
                               string.Format("Data fragmented into {0} pieces", fragments.Count));
            fragInfo.PieceNum = fragments.Count;

#if FUSHARE_PF
            DateTime put_started = DateTime.UtcNow;
#endif
            bool succ;
            if (!concurrently)
            {
                succ = PutFragsSequentially(fragInfo, info_key, ttl, fragments);
            }
            else
            {
                //succ  = PutFragsConcurrently(fragInfo, info_key, ttl, fragments);
                succ = PutFragsInBulk(fragInfo, info_key, ttl, fragments);
            }

#if FUSHARE_PF
            DateTime put_finished = DateTime.UtcNow;
            TimeSpan put_time     = put_finished - put_started;
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("Total time used to put {0}: {1} seconds",
                                             Encoding.UTF8.GetString(fragInfo.BaseKey), put_time));
#endif

            return(succ);
        }
Exemple #5
0
        public void TestPutAndGetFragments()
        {
            MockBrunetDht     mock_dht  = new MockBrunetDht();
            BrunetDht         dht       = new BrunetDht(mock_dht);
            FragmentationInfo frag_info = new FragmentationInfo();

            byte[] b_key = MakeByteArray(20);
            string key   = Encoding.UTF8.GetString(b_key);

            frag_info.BaseKey = Encoding.UTF8.GetString(b_key);
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("key : {0}", Base32.Encode(b_key)));
            byte[]         expected = MakeByteArray(1024 * 10);
            int            ttl      = 1000;
            BrunetDhtEntry bde      = new BrunetDhtEntry(key, expected, ttl);

            dht.PutFragments(bde, frag_info);
            Hashtable ht = mock_dht.HTStorage;

            Assert.AreEqual(11, ht.Count);
            ////
            byte[]            serialized_fragInfo = ((DhtGetResult[])dht.Get(key))[0].value;
            FragmentationInfo frag_info_actual    =
                DictionaryData.CreateDictionaryData(serialized_fragInfo) as FragmentationInfo;

            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("BaseKey: {0}", Base32.Encode(Encoding.UTF8.GetBytes(frag_info_actual.BaseKey))));
            BrunetDhtEntry actual = dht.GetFragments(frag_info) as BrunetDhtEntry;
            MemBlock       mb     = MemBlock.Reference(actual.Value);
            MemBlock       mb_exp = MemBlock.Reference(expected);

            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               mb.ToBase32String().Substring(0, 50));
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               mb_exp.ToBase32String().Substring(0, 50));
            Assert.AreEqual(mb_exp, mb);
        }
Exemple #6
0
 public void TestPutAndGetFragments()
 {
     MockBrunetDht mock_dht = new MockBrunetDht();
       BrunetDht dht = new BrunetDht(mock_dht);
       FragmentationInfo frag_info = new FragmentationInfo();
       byte[] b_key = MakeByteArray(20);
       string key = Encoding.UTF8.GetString(b_key);
       frag_info.BaseKey = Encoding.UTF8.GetString(b_key);
       Logger.WriteLineIf(LogLevel.Verbose, _log_props,
       string.Format("key : {0}", Base32.Encode(b_key)));
       byte[] expected = MakeByteArray(1024 * 10);
       int ttl = 1000;
       BrunetDhtEntry bde = new BrunetDhtEntry(key, expected, ttl);
       dht.PutFragments(bde, frag_info);
       Hashtable ht = mock_dht.HTStorage;
       Assert.AreEqual(11, ht.Count);
       ////
       byte[] serialized_fragInfo = ((DhtGetResult[])dht.Get(key))[0].value;
       FragmentationInfo frag_info_actual =
     DictionaryData.CreateDictionaryData(serialized_fragInfo) as FragmentationInfo;
       Logger.WriteLineIf(LogLevel.Verbose, _log_props,
       string.Format("BaseKey: {0}", Base32.Encode(Encoding.UTF8.GetBytes(frag_info_actual.BaseKey))));
       BrunetDhtEntry actual = dht.GetFragments(frag_info) as BrunetDhtEntry;
       MemBlock mb = MemBlock.Reference(actual.Value);
       MemBlock mb_exp = MemBlock.Reference(expected);
       Logger.WriteLineIf(LogLevel.Verbose, _log_props,
       mb.ToBase32String().Substring(0, 50));
       Logger.WriteLineIf(LogLevel.Verbose, _log_props,
       mb_exp.ToBase32String().Substring(0, 50));
       Assert.AreEqual(mb_exp, mb);
 }
Exemple #7
0
 public DictionaryData GetFragments(FragmentationInfo info)
 {
     return this.GetFragments(info, true);
 }
Exemple #8
0
 /// <summary>
 /// Puts fragments and chooses the concurrent option
 /// </summary>
 public bool PutFragments(BrunetDhtEntry bde, FragmentationInfo fragInfo)
 {
     return(this.PutFragments(bde, fragInfo, true));
 }
Exemple #9
0
        /// <exception cref="Exception">Operation Failed</exception>
        /// <returns>A BrunetDhtEntry that has the whole chunk of data</returns>
        public DictionaryData GetFragments(FragmentationInfo info, bool concurrently)
        {
            BrunetDhtEntry ret = null;
              byte[] base_key = info.BaseKey;
              int piece_num = info.PieceNum;
              MemBlock fragments;
              int largest_age;
              int smallest_ttl;

              /*
               * @TODO: It doesn't have to be sequential but let's first get it work with
               * this approach
               */

            #if FUSHARE_PF
              DateTime get_started = DateTime.UtcNow;
            #endif
              if (!concurrently) {
            fragments = GetFragsSequentially(base_key, piece_num, out largest_age, out smallest_ttl);
              } else {
            //fragments = GetFragsConcurrently(base_key, piece_num, out largest_age, out smallest_ttl);
            fragments = GetFragsInBulk(base_key, piece_num, out largest_age, out smallest_ttl);
              }

            #if FUSHARE_PF
              DateTime get_finished = DateTime.UtcNow;
              TimeSpan get_time = get_finished - get_started;
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("Total time used to get {0}: {1} seconds",
            Encoding.UTF8.GetString(base_key), get_time));
            #endif
              if (fragments != null) {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("Fragments successfully got from DHT"));

            //Got the fragments correctly
            ret = new BrunetDhtEntry(base_key, (new RegularData(fragments)).SerializeTo(),
            largest_age, smallest_ttl);
            return ret;
              } else {
            Logger.WriteLineIf(LogLevel.Error, _log_props,
              string.Format("DHT Get of fragments failed"));
            throw new Exception("DHT Get of fragments failed.");
              }
        }
Exemple #10
0
 public DictionaryData GetFragments(FragmentationInfo info)
 {
     return(this.GetFragments(info, true));
 }
Exemple #11
0
        /// <summary>
        /// Concurrently puts pieces into DHT
        /// </summary>
        /// <returns>True if successful</returns>
        private bool PutFragsConcurrently(FragmentationInfo fragInfo,
                                          byte[] infoKey, int ttl, IList <FingerprintedData> fragments)
        {
            bool ret;
            //prepare the global state
            int                      max_enqueues = 1; //we only need a true/false answer
            BlockingQueue            bq_result    = new BlockingQueue(max_enqueues);
            AsyncPutFragsGlobalState global_state =
                new AsyncPutFragsGlobalState(fragments.Count, fragInfo.BaseKey, bq_result);
            //@TODO tweak the number of concurrency_degree here.
            int concurrency_degree = Concurrency;

            global_state.Concurrency = concurrency_degree;
            //Put pieces
            for (int index = 0; index < fragments.Count; index++)
            {
                FingerprintedData fpd           = fragments[index];
                byte[]            serializedFpd = fpd.SerializeTo();
                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("Size after serialization {0}", serializedFpd.Length));
                byte[] piece_key        = BuildFragmentKey(fragInfo.BaseKey, index);
                string piece_key_string = Encoding.UTF8.GetString(piece_key);
                //piece state
                AsyncOpState      aps  = new AsyncOpState(piece_key, serializedFpd, ttl);
                AsyncFragsOpState apfs = new AsyncFragsOpState(global_state, aps);
                //async put, one instance of IDht per put because thread safty not guaranteed
                IDht proxy = DhtServiceClient.GetXmlRpcDhtClient(_svc_uri.Port);
                BrunetDhtClientOperations brdht_ops = new BrunetDhtClientOperations(
                    proxy);
                // Fire the async XML-RPC call.
                lock (global_state.SyncRoot) {
                    brdht_ops.BeginPutWithCallback(piece_key, serializedFpd, ttl,
                                                   new AsyncCallback(this.OnDhtPutReturns), apfs);
                }

                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("Put piece {0} to DHT began (asynchronously)",
                                                 piece_key_string));

                if ((concurrency_degree > 1 && (index + 1) % concurrency_degree == 0) ||
                    index == fragments.Count - 1)
                {
                    // Stop to wait for batch finish or all finish
                    global_state.BatchFinishedEvent.WaitOne();
                    if (concurrency_degree > 1)
                    {
                        Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                           string.Format("Batch {0} finished. Moving on",
                                                         (int)((index + 1) / concurrency_degree)));
                    }
                }
            }

            //block here until result comes
            PutFragsStoppedEventArgs stop_args =
                (PutFragsStoppedEventArgs)bq_result.Dequeue();

            // Deal with info object.
            if (stop_args.IsSuccessful)
            {
                ret = _dht.Put(infoKey, fragInfo.SerializeTo(), ttl);
                if (ret)
                {
                    Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                       string.Format("FragmentationInfo {0} successfully put",
                                                     Encoding.UTF8.GetString(infoKey)));
                }
            }
            else
            {
                ret = false;
            }

            return(ret);
        }
Exemple #12
0
        /// <summary>
        /// Put with a size limit. Data larger than the limit will be splitted into
        /// pieces and put to different under different DHT keys.
        /// </summary>
        /// <param name="maxSize">The size limit</param>
        /// <param name="split">Whether to split the oversized data</param>
        /// <exception cref="ArgumentException">Data larger than the limit and 
        /// split specified as false</exception>
        public bool Put(byte[] key, byte[] value, int ttl, int maxSize, bool split)
        {
            bool result;
              if (value.Length > maxSize) {
            if (split) {
              BrunetDhtEntry bde = new BrunetDhtEntry(key, value, ttl);
              FragmentationInfo frag_info = new FragmentationInfo(key);
              frag_info.PieceLength = maxSize;
              result = PutFragments(bde, frag_info);
            } else {
              throw new ArgumentException("Data too large but split opted out.");
            }
              } else {
            result = _dht.Put(key, value, ttl);
              }

              return result;
        }
Exemple #13
0
        private bool PutFragsInBulk(FragmentationInfo fragInfo,
            byte[] infoKey, int ttl, IList<FingerprintedData> fragments)
        {
            string info_key_string = Encoding.UTF8.GetString(infoKey);
              XmlRpcStruct[] parameters = new XmlRpcStruct[fragments.Count];
              // Prepare parameters for bulk put.
              int index = 0;
              foreach (FingerprintedData fpd in fragments) {
            byte[] serializedFpd = fpd.SerializeTo();
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
              string.Format("Size of piece {0} after serialization: {1}", index,
              serializedFpd.Length));
            byte[] piece_key = BuildFragmentKey(fragInfo.BaseKey, index);
            XmlRpcStruct param_dict = new XmlRpcStruct();
            param_dict.Add("name", piece_key);
            param_dict.Add("value", serializedFpd);
            param_dict.Add("ttl", ttl);
            parameters[index] = param_dict;
            index++;
              }

              bool[] results;
              try {
            results = _dht.BulkPut(parameters);
              } catch (Exception ex) {
            // Network related operation, log the exception and let it be handled
            // upper stream caller.
            Logger.WriteLineIf(LogLevel.Error, _log_props,
              string.Format("Exception caught in BulkPut"));
            Logger.WriteLineIf(LogLevel.Error, _log_props,
              ex);
            throw;
              }

              IList<int> failed_pieces = new List<int>();
              for (int i = 0; i < results.Length; i++) {
            bool result = results[i];
            if (!result) {
              failed_pieces.Add(i);
            }
              }

              // Log failed pieces
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("Failed {0} pieces are:", failed_pieces.Count));
              StringBuilder sb = new StringBuilder();
              foreach (int pieceIndx in failed_pieces) {
            sb.Append(pieceIndx);
            sb.Append(" ");
              }
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            sb.ToString());

              // Decide whether to retry.
              if (failed_pieces.Count > 20) {
            Logger.WriteLineIf(LogLevel.Info, _log_props,
              string.Format("Too many pieces failed. Returning..."));
            return false;
              }

              //Retry failed pieces.
              foreach (int pieceIndx in failed_pieces) {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
              string.Format("Retrying piece {0}", pieceIndx));
            bool succ_retries = PutWithRetries((byte[])parameters[pieceIndx]["name"], (byte[])
              parameters[pieceIndx]["value"], (int)parameters[pieceIndx]["ttl"], 2);
            if (!succ_retries) {
              // Cannot succeed on this piece even after retry...
              return false;
            }
              }

              //Put info
              bool succ_info = PutWithRetries(infoKey, fragInfo.SerializeTo(), ttl, 2);
              return succ_info;
        }
Exemple #14
0
        private bool PutFragsSequentially(FragmentationInfo fragInfo,
                                          byte[] infoKey, int ttl, IList <FingerprintedData> fragments)
        {
            string info_key_string = Encoding.UTF8.GetString(infoKey);
            //Put pieces
            int index = 0;

            foreach (FingerprintedData fpd in fragments)
            {
                byte[] serializedFpd = fpd.SerializeTo();
                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("Size after serialization {0}", serializedFpd.Length));
                int    i                = index++;
                bool   succ             = false;
                int    retries          = 3;
                byte[] piece_key        = BuildFragmentKey(fragInfo.BaseKey, i);
                string piece_key_string = Encoding.UTF8.GetString(piece_key);
                for (; !succ && retries > 0; retries--)
                {
                    if (retries < 3)
                    {
                        Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                           string.Format("Retrying..."));
                    }

                    succ = _dht.Put(piece_key, serializedFpd, ttl);
                    if (!succ)
                    {
                        Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                           string.Format("Put failed."));
                    }
                }

                if (retries <= 0)
                {
                    Logger.WriteLineIf(LogLevel.Error, _log_props,
                                       string.Format("Retries exhausted when putting piece : {0}",
                                                     piece_key_string));
                    return(false);
                }
                else
                {
                    Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                       string.Format("Piece {0} successfully put to DHT", piece_key_string));
                }
            }

            //Put info
            bool succ_info    = false;
            int  retries_info = 3;

            for (; !succ_info && retries_info > 0; retries_info--)
            {
                if (retries_info < 3)
                {
                    Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                       string.Format("Retrying..."));
                }
                succ_info = _dht.Put(infoKey, fragInfo.SerializeTo(), ttl);
            }

            if (retries_info <= 0)
            {
                Logger.WriteLineIf(LogLevel.Error, _log_props,
                                   string.Format("Retries exhausted when putting FragmentationInfo : {0}",
                                                 info_key_string));
                return(false);
            }
            else
            {
                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("FragmentationInfo successfully put to DHT with name {0}",
                                                 info_key_string));
            }
            return(true);
        }
Exemple #15
0
        private bool PutFragsSequentially(FragmentationInfo fragInfo, 
            byte[] infoKey, int ttl, IList<FingerprintedData> fragments)
        {
            string info_key_string = Encoding.UTF8.GetString(infoKey);
              //Put pieces
              int index = 0;
              foreach (FingerprintedData fpd in fragments) {
            byte[] serializedFpd = fpd.SerializeTo();
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("Size after serialization {0}", serializedFpd.Length));
            int i = index++;
            bool succ = false;
            int retries = 3;
            byte[] piece_key = BuildFragmentKey(fragInfo.BaseKey, i);
            string piece_key_string = Encoding.UTF8.GetString(piece_key);
            for (; !succ && retries > 0; retries--) {
              if (retries < 3) {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                string.Format("Retrying..."));
              }

              succ = _dht.Put(piece_key, serializedFpd, ttl);
              if (!succ) {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                      string.Format("Put failed."));
              }
            }

            if (retries <= 0) {
              Logger.WriteLineIf(LogLevel.Error, _log_props,
              string.Format("Retries exhausted when putting piece : {0}",
              piece_key_string));
              return false;
            } else {
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
              string.Format("Piece {0} successfully put to DHT", piece_key_string));
            }
              }

              //Put info
              bool succ_info = false;
              int retries_info = 3;
              for (; !succ_info && retries_info > 0; retries_info--) {
            if (retries_info < 3) {
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
              string.Format("Retrying..."));
            }
            succ_info = _dht.Put(infoKey, fragInfo.SerializeTo(), ttl);
              }

              if (retries_info <= 0) {
            Logger.WriteLineIf(LogLevel.Error, _log_props,
            string.Format("Retries exhausted when putting FragmentationInfo : {0}",
            info_key_string));
            return false;
              } else {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("FragmentationInfo successfully put to DHT with name {0}",
            info_key_string));
              }
              return true;
        }
Exemple #16
0
        /// <summary>
        /// Puts fragments to Dht.
        /// </summary>
        /// <param name="bde">The data object.</param>
        /// <param name="fragInfo">Object that contains the meta info.</param>
        /// <param name="concurrently">Puts concurrently if set to true</param>
        /// <returns>True if the operation succeeds.</returns>
        public bool PutFragments(BrunetDhtEntry bde, FragmentationInfo fragInfo, 
            bool concurrently)
        {
            byte[] info_key = bde.Key;
              int ttl = bde.Ttl;  //This ttl is used by every piece and the frag info
              MemBlock data = MemBlock.Reference(bde.Value);
              int piece_length = 0;
              int offset = 0;
              IList<FingerprintedData> fragments = new List<FingerprintedData>();
              while (offset < data.Length) {
            piece_length = (offset + fragInfo.PieceLength > data.Length) ?
            data.Length - offset : fragInfo.PieceLength;
            MemBlock piece = data.Slice(offset, piece_length);
            offset += piece_length;
            FingerprintedData fpd = new FingerprintedData(new RegularData(piece));
            fragments.Add(fpd);
              }

              //Update the piece number in fragInfo.
              Logger.WriteLineIf(LogLevel.Info, _log_props,
              string.Format("Data fragmented into {0} pieces", fragments.Count));
              fragInfo.PieceNum = fragments.Count;

            #if FUSHARE_PF
              DateTime put_started = DateTime.UtcNow;
            #endif
              bool succ;
              if (!concurrently) {
            succ = PutFragsSequentially(fragInfo, info_key, ttl, fragments);
              } else {
            //succ  = PutFragsConcurrently(fragInfo, info_key, ttl, fragments);
            succ = PutFragsInBulk(fragInfo, info_key, ttl, fragments);
              }

            #if FUSHARE_PF
              DateTime put_finished = DateTime.UtcNow;
              TimeSpan put_time = put_finished - put_started;
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("Total time used to put {0}: {1} seconds",
            Encoding.UTF8.GetString(fragInfo.BaseKey), put_time));
            #endif

              return succ;
        }
Exemple #17
0
 /// <summary>
 /// Puts fragments and chooses the concurrent option
 /// </summary>
 public bool PutFragments(BrunetDhtEntry bde, FragmentationInfo fragInfo)
 {
     return this.PutFragments(bde, fragInfo, true);
 }
Exemple #18
0
        private bool PutFragsInBulk(FragmentationInfo fragInfo,
                                    byte[] infoKey, int ttl, IList <FingerprintedData> fragments)
        {
            string info_key_string = Encoding.UTF8.GetString(infoKey);

            XmlRpcStruct[] parameters = new XmlRpcStruct[fragments.Count];
            // Prepare parameters for bulk put.
            int index = 0;

            foreach (FingerprintedData fpd in fragments)
            {
                byte[] serializedFpd = fpd.SerializeTo();
                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("Size of piece {0} after serialization: {1}", index,
                                                 serializedFpd.Length));
                byte[]       piece_key  = BuildFragmentKey(fragInfo.BaseKey, index);
                XmlRpcStruct param_dict = new XmlRpcStruct();
                param_dict.Add("name", piece_key);
                param_dict.Add("value", serializedFpd);
                param_dict.Add("ttl", ttl);
                parameters[index] = param_dict;
                index++;
            }

            bool[] results;
            try {
                results = _dht.BulkPut(parameters);
            } catch (Exception ex) {
                // Network related operation, log the exception and let it be handled
                // upper stream caller.
                Logger.WriteLineIf(LogLevel.Error, _log_props,
                                   string.Format("Exception caught in BulkPut"));
                Logger.WriteLineIf(LogLevel.Error, _log_props,
                                   ex);
                throw;
            }

            IList <int> failed_pieces = new List <int>();

            for (int i = 0; i < results.Length; i++)
            {
                bool result = results[i];
                if (!result)
                {
                    failed_pieces.Add(i);
                }
            }

            // Log failed pieces
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("Failed {0} pieces are:", failed_pieces.Count));
            StringBuilder sb = new StringBuilder();

            foreach (int pieceIndx in failed_pieces)
            {
                sb.Append(pieceIndx);
                sb.Append(" ");
            }
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               sb.ToString());

            // Decide whether to retry.
            if (failed_pieces.Count > 20)
            {
                Logger.WriteLineIf(LogLevel.Info, _log_props,
                                   string.Format("Too many pieces failed. Returning..."));
                return(false);
            }

            //Retry failed pieces.
            foreach (int pieceIndx in failed_pieces)
            {
                Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                   string.Format("Retrying piece {0}", pieceIndx));
                bool succ_retries = PutWithRetries((byte[])parameters[pieceIndx]["name"], (byte[])
                                                   parameters[pieceIndx]["value"], (int)parameters[pieceIndx]["ttl"], 2);
                if (!succ_retries)
                {
                    // Cannot succeed on this piece even after retry...
                    return(false);
                }
            }

            //Put info
            bool succ_info = PutWithRetries(infoKey, fragInfo.SerializeTo(), ttl, 2);

            return(succ_info);
        }
Exemple #19
0
        /// <summary>
        /// Concurrently puts pieces into DHT
        /// </summary>
        /// <returns>True if successful</returns>
        private bool PutFragsConcurrently(FragmentationInfo fragInfo,
            byte[] infoKey, int ttl, IList<FingerprintedData> fragments)
        {
            bool ret;
              //prepare the global state
              int max_enqueues = 1; //we only need a true/false answer
              BlockingQueue bq_result = new BlockingQueue(max_enqueues);
              AsyncPutFragsGlobalState global_state =
              new AsyncPutFragsGlobalState(fragments.Count, fragInfo.BaseKey, bq_result);
              //@TODO tweak the number of concurrency_degree here.
              int concurrency_degree = Concurrency;
              global_state.Concurrency = concurrency_degree;
              //Put pieces
              for (int index = 0; index < fragments.Count; index++) {
            FingerprintedData fpd = fragments[index];
            byte[] serializedFpd = fpd.SerializeTo();
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("Size after serialization {0}", serializedFpd.Length));
            byte[] piece_key = BuildFragmentKey(fragInfo.BaseKey, index);
            string piece_key_string = Encoding.UTF8.GetString(piece_key);
            //piece state
            AsyncOpState aps = new AsyncOpState(piece_key, serializedFpd, ttl);
            AsyncFragsOpState apfs = new AsyncFragsOpState(global_state, aps);
            //async put, one instance of IDht per put because thread safty not guaranteed
            IDht proxy = DhtServiceClient.GetXmlRpcDhtClient(_svc_uri.Port);
            BrunetDhtClientOperations brdht_ops = new BrunetDhtClientOperations(
              proxy);
            // Fire the async XML-RPC call.
            lock (global_state.SyncRoot) {
              brdht_ops.BeginPutWithCallback(piece_key, serializedFpd, ttl,
              new AsyncCallback(this.OnDhtPutReturns), apfs);
            }

            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
              string.Format("Put piece {0} to DHT began (asynchronously)",
              piece_key_string));

            if ((concurrency_degree > 1 && (index + 1) % concurrency_degree == 0) ||
              index == fragments.Count - 1) {
              // Stop to wait for batch finish or all finish
              global_state.BatchFinishedEvent.WaitOne();
              if (concurrency_degree > 1) {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
              string.Format("Batch {0} finished. Moving on",
              (int)((index + 1) / concurrency_degree)));
              }
            }
              }

              //block here until result comes
              PutFragsStoppedEventArgs stop_args =
            (PutFragsStoppedEventArgs)bq_result.Dequeue();

              // Deal with info object.
              if (stop_args.IsSuccessful) {
            ret = _dht.Put(infoKey, fragInfo.SerializeTo(), ttl);
            if (ret) {
              Logger.WriteLineIf(LogLevel.Verbose, _log_props,
            string.Format("FragmentationInfo {0} successfully put",
            Encoding.UTF8.GetString(infoKey)));
            }
              } else {
            ret = false;
              }

              return ret;
        }