public DataEntry(string key, ETag lastOwner, List<int> senderPath)
 {
     this.key = key;
     this.lastOwnerID = lastOwner.UID;
     this.lastOwnerRevision = lastOwner.Revision;
     this.senderPath = senderPath;
 }
 public DataHeader(string key, ETag version, List<int> sentFrom)
 {
     this.key = key;
     this.lastOwnerID = version.UID;
     this.lastOwnerRevision = version.Revision;
     this.sentFrom = sentFrom;
 }
        public DataHeader(string key, ETag version, int sentFromID)
        {
            this.key = key;
            this.lastOwnerID = version.UID;
            this.lastOwnerRevision = version.Revision;

            this.sentFrom = new List<int>() { sentFromID };
        }
        public DataEntry(string key, object value, ETag lastOwner, List<int> senderPath,bool subscribed)
        {
            this.key = key;
            this.value = value;
            this.lastOwnerID = lastOwner.UID;
            this.lastOwnerRevision = lastOwner.Revision;
            this.senderPath = senderPath;
            this.subscribed = subscribed;

            DetectTypeFromValue();
        }
Beispiel #5
0
 public static ETagCompare CompareETags(ETag first, ETag second)
 {
     if (first.Revision > second.Revision)
     {
         return ETagCompare.FirstIsNewer;
     }
     else if (first.Revision < second.Revision)
     {
         return ETagCompare.SecondIsNewer;
     }
     else if (first.UID == second.UID)
     {
         return ETagCompare.Same;
     }
     else
     {
         return ETagCompare.Conflict;
     }
 }
        private void WriteMethodPush(string resource,List<int> senderList, List<int> proxyResponsePath, int contentLength,
            string mimeType, ETag lastVer, bool isDeleted, bool willClose, MemoryStream bufferedOutput)
        {
            StreamWriter writer = new StreamWriter(bufferedOutput, Encoding.ASCII);

            writer.NewLine = NEWLINE;

            if (isDeleted)
            {
                WriteMethodDeleted(bufferedOutput, resource, senderList, proxyResponsePath, lastVer.UID, lastVer.Revision);
            }
            else
            {
                WriteMethodHeader(writer, resource, mimeType, contentLength, lastVer.UID, lastVer.Revision, senderList, proxyResponsePath, willClose);
            }
        }
        /// <summary>
        /// TODO: add in some code to reduce round-trips to simple data types 
        /// </summary>
        /// <param name="reader">File to read</param>
        /// <param name="sentFromList">Sent from list</param>
        /// <param name="getEntriesFromSender">This function fills in a list of entries that need to be requested from the sender</param>
        /// <param name="addEntriesToSender">These are entries that the sender does not know about</param>
        /// <seealso cref="ReadHeadStub"/>
        private void ReadDictionaryTextFile(StreamReader reader, List<int> sentFromList, List<DataHeader> getEntriesFromSender, List<SendMemoryToPeer> addEntriesToSender)
        {
            // 0 - key name
            // 1 - owner
            // 2 - revision
            // 3 - rw flag
            // 4 - MIME type

            // WriteDebug(this.local_uid + " ReadDictionaryTextFile");

            string nsLine = reader.ReadLine();
            string[] nsLineParts = nsLine.Split('\t');

            System.Diagnostics.Debug.Assert(nsLineParts[0] == DATA_NAMESPACE + "/");

            // if the owner of the dictionary is the same as myself, skip reading the changes
            if (nsLineParts[1] == this.local_uid.ToString())
            {
                throw new NotSupportedException("ReadDictionaryTextFile cannot read itself");// i want to see if this actually can happen (only when multiple connections happen on the same server)

            }

            int itemCount = int.Parse(nsLineParts[4]); // count of all the items in the dictionary

            List<DataEntry> entriesCovered = new List<DataEntry>(itemCount + this.data.Count);

            for (int i = 0; i < itemCount; i++)
            {
                nsLine = reader.ReadLine();
                nsLineParts = nsLine.Split('\t');
                //WriteDebug(nsLine);

                DataHeader getEntry = null;
                SendMemoryToPeer addEntryToSender = null;

                ETag tag = new ETag(int.Parse(nsLineParts[1]), int.Parse(nsLineParts[2]));

                // this entry is used only to call ReadMimeSimpleData
                DataEntry fakeEntry = new DataEntry("/fake", tag, new List<int>(0));
                fakeEntry.ReadMimeSimpleData(nsLineParts[4]);

                dataLock.EnterReadLock();
                try
                {
                    if (this.data.ContainsKey(nsLineParts[0]))
                    {
                        entriesCovered.Add(this.data[nsLineParts[0]]);
                    }
                }
                finally { dataLock.ExitReadLock(); }

                // the dictionary does not report the current sender so let's tack it on
                List<int> listOfSenders = new List<int>(GetArrayOf(nsLineParts[5]));
                if (!listOfSenders.Contains(this.remote_uid))
                    listOfSenders.Add(this.remote_uid);

                ResponseAction action = ReadDataStub(nsLineParts[0], fakeEntry.GetMime(), nsLineParts[1] + "." + nsLineParts[2], new List<int>( listOfSenders), out getEntry, out addEntryToSender);

                if (getEntry != null)
                {
                    getEntriesFromSender.Add(getEntry);
                }
                if (addEntryToSender != null)
                {
                    addEntriesToSender.Add(addEntryToSender);
                }

                if (action == ResponseAction.ForwardToAll)
                {
                    listOfSenders.Clear();
                }
                if (action != ResponseAction.DoNotForward)
                {
                    DataEntry get = P2PDictionary.GetEntry( this.data, this.dataLock, nsLineParts[0]);
                    System.Diagnostics.Debug.Assert(get != null);

                    listOfSenders.Add(this.local_uid);
                    SendBroadcastMemory msg = new SendBroadcastMemory(get.key , listOfSenders);
                    WriteMethodPush(get.key, listOfSenders, null, 0, get.GetMime(), get.GetETag(), get.IsEmpty, false, msg.MemBuffer);
                    this.controller.BroadcastToWire(msg);
                }
            }

            // now check to see which dictionary entries that the sender does not have; i'll send my entries to the caller
            this.dataLock.EnterWriteLock();
            try
            {
                foreach (KeyValuePair<string, DataEntry> senderDoesNotHave in this.data.SkipWhile(x => entriesCovered.Contains(x.Value)))
                {
                    DataEntry get = senderDoesNotHave.Value;

                    // i know about something that the sender does not know
                    SendMemoryToPeer mem = new SendMemoryToPeer(get.key, sentFromList);
                    WriteMethodPush(get.key, GetListOfThisLocalID(), null, 0, get.GetMime(), get.GetETag(), get.IsEmpty, false, mem.MemBuffer);
                    addEntriesToSender.Add(mem);
                }
            }
            finally { this.dataLock.ExitWriteLock();}
        }