示例#1
0
        public void TestCompare()
        {
            ByteArrayComparer comparer = new ByteArrayComparer();

            byte[] x = new byte[0], y = new byte[0];
            comparer.Compare(x, y).Should().Be(0);

            x = new byte[] { 1 };
            comparer.Compare(x, y).Should().Be(1);
            y = x;
            comparer.Compare(x, y).Should().Be(0);

            x = new byte[] { 1 };
            y = new byte[] { 2 };
            comparer.Compare(x, y).Should().Be(-1);
        }
示例#2
0
        public void TestCompare()
        {
            ByteArrayComparer comparer = ByteArrayComparer.Default;

            byte[] x = new byte[0], y = new byte[0];
            comparer.Compare(x, y).Should().Be(0);

            x = new byte[] { 1 };
            comparer.Compare(x, y).Should().Be(1);
            y = x;
            comparer.Compare(x, y).Should().Be(0);

            x = new byte[] { 1 };
            y = new byte[] { 2 };
            comparer.Compare(x, y).Should().Be(-1);

            comparer = ByteArrayComparer.Reverse;
            x        = new byte[] { 3 };
            comparer.Compare(x, y).Should().Be(-1);
            y = x;
            comparer.Compare(x, y).Should().Be(0);

            x = new byte[] { 1 };
            y = new byte[] { 2 };
            comparer.Compare(x, y).Should().Be(1);
        }
示例#3
0
 public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte table, byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward)
 {
     ByteArrayComparer comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse;
     IEnumerable<KeyValuePair<byte[], byte[]>> records = immutableData[table];
     if (keyOrPrefix?.Length > 0)
         records = records.Where(p => comparer.Compare(p.Key, keyOrPrefix) >= 0);
     records = records.OrderBy(p => p.Key, comparer);
     return records.Select(p => (p.Key, p.Value));
 }
示例#4
0
        /// <summary>
        /// Seek to the entry with specific key
        /// </summary>
        /// <param name="keyOrPrefix">The key to be sought</param>
        /// <param name="direction">The direction of seek</param>
        /// <returns>An enumerator containing all the entries after seeking.</returns>
        public IEnumerable <(TKey Key, TValue Value)> Seek(byte[] keyOrPrefix = null, SeekDirection direction = SeekDirection.Forward)
        {
            IEnumerable <(byte[], TKey, TValue)> cached;
            HashSet <TKey>    cachedKeySet;
            ByteArrayComparer comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse;

            lock (dictionary)
            {
                cached = dictionary
                         .Where(p => p.Value.State != TrackState.Deleted && (keyOrPrefix == null || comparer.Compare(p.Key.ToArray(), keyOrPrefix) >= 0))
                         .Select(p =>
                                 (
                                     KeyBytes: p.Key.ToArray(),
                                     p.Key,
                                     p.Value.Item
                                 ))
                         .OrderBy(p => p.KeyBytes, comparer)
                         .ToArray();
                cachedKeySet = new HashSet <TKey>(dictionary.Keys);
            }
            var uncached = SeekInternal(keyOrPrefix ?? Array.Empty <byte>(), direction)
                           .Where(p => !cachedKeySet.Contains(p.Key))
                           .Select(p =>
                                   (
                                       KeyBytes: p.Key.ToArray(),
                                       p.Key,
                                       p.Value
                                   ));

            using (var e1 = cached.GetEnumerator())
                using (var e2 = uncached.GetEnumerator())
                {
                    (byte[] KeyBytes, TKey Key, TValue Item)i1, i2;
                    bool c1 = e1.MoveNext();
                    bool c2 = e2.MoveNext();
                    i1 = c1 ? e1.Current : default;
                    i2 = c2 ? e2.Current : default;
                    while (c1 || c2)
                    {
                        if (!c2 || (c1 && comparer.Compare(i1.KeyBytes, i2.KeyBytes) < 0))
                        {
                            yield return(i1.Key, i1.Item);

                            c1 = e1.MoveNext();
                            i1 = c1 ? e1.Current : default;
                        }
                        else
                        {
                            yield return(i2.Key, i2.Item);

                            c2 = e2.MoveNext();
                            i2 = c2 ? e2.Current : default;
                        }
                    }
                }
        }
示例#5
0
            public void LowerContextInputLengthIs5()
            {
                byte[] input    = { 10, 11, 12, 13, 14 };
                byte[] expected = { 11, 12, 13, 14 };
                var    entry    = new Entry(11, input);

                entry.NextContext();
                var actual = entry.Context;

                var byteArrayComparer = new ByteArrayComparer();

                Assert.AreEqual(0, byteArrayComparer.Compare(expected, actual));
            }
示例#6
0
        /// <summary>
        /// Find the entries that between [start, end)
        /// </summary>
        /// <param name="direction">The search direction.</param>
        /// <returns>Entries found with the desired range</returns>
        public IEnumerable <(TKey Key, TValue Value)> FindRange(byte[] start, byte[] end, SeekDirection direction = SeekDirection.Forward)
        {
            ByteArrayComparer comparer = direction == SeekDirection.Forward
                ? ByteArrayComparer.Default
                : ByteArrayComparer.Reverse;

            foreach (var(key, value) in Seek(start, direction))
            {
                if (comparer.Compare(key.ToArray(), end) < 0)
                {
                    yield return(key, value);
                }
            }
        }
示例#7
0
        public IEnumerable <(byte[] Key, byte[] Value)> Seek(byte table, byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward)
        {
            ByteArrayComparer comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse;
            IEnumerable <KeyValuePair <byte[], byte[]> > records = innerData[table];

            if (keyOrPrefix?.Length > 0)
            {
                records = records.Where(p => comparer.Compare(p.Key, keyOrPrefix) >= 0);
            }
            records = records.OrderBy(p => p.Key, comparer);
            foreach (var pair in records)
            {
                yield return(pair.Key, pair.Value);
            }
        }
示例#8
0
 public void TestByteArrayComparer()
 {
     string[] ss = new string[] { "", "asd", "ass", "qwer", "qwe" };
       StringComparer sComp = StringComparer.InvariantCulture;
       ByteArrayComparer bComp = new ByteArrayComparer();
       for (int i=0; i<ss.Length; i++)
     for (int j = 0; j < ss.Length; j++)
     {
       string sa = ss[i];
       string sb = ss[j];
       byte[] ba = Encoding.ASCII.GetBytes(sa);
       byte[] bb = Encoding.ASCII.GetBytes(sb);
       Assert.AreEqual(
     sComp.Compare(sa, sb),
     bComp.Compare(ba, bb));
     }
 }
示例#9
0
        public void TestByteArrayComparer()
        {
            string[]          ss    = new string[] { "", "asd", "ass", "qwer", "qwe" };
            StringComparer    sComp = StringComparer.InvariantCulture;
            ByteArrayComparer bComp = new ByteArrayComparer();

            for (int i = 0; i < ss.Length; i++)
            {
                for (int j = 0; j < ss.Length; j++)
                {
                    string sa = ss[i];
                    string sb = ss[j];
                    byte[] ba = Encoding.ASCII.GetBytes(sa);
                    byte[] bb = Encoding.ASCII.GetBytes(sb);
                    Assert.AreEqual(
                        sComp.Compare(sa, sb),
                        bComp.Compare(ba, bb));
                }
            }
        }
示例#10
0
        public IEnumerable <uint> FindRecordIds(Expression <Func <T, object> > propertySelector, object propertyValue)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("JsonDocumentCollection");
            }

            if (propertySelector == null)
            {
                throw new ArgumentNullException(nameof(propertySelector));
            }

            var property = ReflectionHelper.PropertyFromLambda(propertySelector);

            if (property == null)
            {
                throw new ArgumentOutOfRangeException(nameof(propertySelector) + ": Only properties are supported.");
            }

            var byteValue = ByteArrayHelper.GetBytes(propertyValue, property.PropertyType);

            var index = this.GetIndex(property.Name);

            if (index == null)
            {
                yield break;
            }

            foreach (var entry in index.LargerThanOrEqualTo(byteValue))
            {
                // As soon as we reached larger key than the key given by client, stop
                if (ByteArrayComparer.Compare(entry.Item1, byteValue) > 0)
                {
                    break;
                }

                // Still in range, yield return
                yield return(entry.Item2);
            }
        }
示例#11
0
 int IComparable <byte[]> .CompareTo(byte[] other)
 {
     return(ByteArrayComparer.Compare(Value, other));
 }
示例#12
0
 public void NullsEqual()
 {
     Assert.Equal(0, _comparer.Compare(null, null));
     Assert.True(ByteArrayComparer.ArraysEqual(null, null));
     Assert.True(_comparer.Equals(null, null));
 }
示例#13
0
        /// <summary>
        /// Attempts to read from this operator's underlying input stream(s) until the next set of
        /// bindings is found which can be outputted by this operator.
        /// </summary>
        /// <returns>
        ///   <c>true</c> if a next binding set is found available to output; otherwise, <c>false</c>.
        /// </returns>
        internal override bool TryReadNext()
        {
            if (!m_tmpDbsCreated)
            {
                if (!m_left.HasNext || !m_right.HasNext)
                {
                    return(false);
                }

                CreateTmpDbs();
            }

            if (m_currentChunkList.Count > 0)
            {
                //
                // if there are still matches available for the current chunk, then simply fetch
                // the next one of those and return it (it's always a join match)
#if DEBUG
                m_planOperator.StartCPUWork();
#endif
                var binding = m_currentChunkList.Dequeue();
                m_next    = Merge(binding, m_rightNext);
                m_hasNext = true;
#if DEBUG
                m_planOperator.StopCPUWork();
                m_planOperator.AddResult();
#endif
                return(true);
            }

            if (m_chunkTable.Count == 0)
            {
                //
                // if the current chunk table is empty, try to advance to the next chunk. if we
                // cannot advance then no more matches are possible.

                if (!AdvanceChunk())
                {
                    m_hasNext = false;
                    return(false);
                }
            }
#if DEBUG
            m_planOperator.StartCPUWork();
#endif
            while (AdvanceRight())
            {
                //
                // bindings from the left operator are in the chunk table; those from the right
                // operator are then matched against those one by one. as long as we can advance
                // the right input stream, more matches are potentially possible.

                var h = m_cursorRight.Current.Key.Data;
                var c = m_byteComparer.Compare(h, m_currentChunk);

                if (c == 0)
                {
                    //
                    // if the two hashes are equal it is possible that matches exist in the chunk
                    // table

                    var k = GetChunkTableKey(m_rightNext);

                    if (m_chunkTable.ContainsKey(k))
                    {
                        //
                        // matches exist in the chunk table. enqueue them in the current chunk
                        // list.

                        foreach (var b in m_chunkTable[k])
                        {
                            m_currentChunkList.Enqueue(b);
                        }

                        //
                        // same code here for fetching a match from the chunk queue and merging
                        // and returning it

                        var binding = m_currentChunkList.Dequeue();
                        m_next    = Merge(binding, m_rightNext);
                        m_hasNext = true;
#if DEBUG
                        m_planOperator.StopCPUWork();
                        m_planOperator.AddResult();
#endif
                        return(true);
                    }
                }
                else if (c > 0)
                {
                    //
                    // if the right hash succeeds the one from the current chunk, then it is time
                    // to advance to the next chunk. we'll also need to tell the right input stream
                    // cursor to not advance (this is kinda hacky as BerkeleyDB doesn't properly
                    // support moving backwards with a cursor).

                    m_cursorRightMovePrev = true;
                    if (!AdvanceChunk())
                    {
                        m_hasNext = false;
#if DEBUG
                        m_planOperator.StopCPUWork();
#endif
                        return(false);
                    }
                }
            }

            //
            // if we arrive here then no more matches are possible

#if DEBUG
            m_planOperator.StopCPUWork();
#endif
            m_hasNext = false;
            return(false);
        }
示例#14
0
        protected override IEnumerable <(TKey, TValue)> SeekInternal(byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward)
        {
            ByteArrayComparer comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse;

            return(InnerDict.Where(kvp => comparer.Compare(kvp.Key.ToArray(), keyOrPrefix) >= 0).Select(p => (p.Key, p.Value)));
        }
示例#15
0
        /// <summary>
        /// Returns the slave device of the specified type, with the specified address, on the specified master channel.
        /// </summary>
        /// <typeparam name="T">Slave type</typeparam>
        /// <param name="address">slave address</param>
        /// <param name="channel">master channel</param>
        /// <returns>Slave device</returns>
        public T GetSlave <T>(int channel, byte[] address)
        {
            var bComp = new ByteArrayComparer();
            //TODO: Check whether only one slave meets the conditions.
            var container = m_SlaveContainers.FirstOrDefault(x => x.Info.MasterChannel == channel && bComp.Compare(x.Slave.OneWireAddress, address));

            if (container == null)
            {
                throw new Exception($"Device with specified address {BitConverter.ToString(address)} not found on channel {channel}");
            }

            if (container != null && container.Slave is T)
            {
                return((T)container.Slave);
            }
            else
            {
                throw new Exception("Specified device type not matchs.");
            }
        }