/// <summary>
        /// Will try to add a new document key and expand all column containers to make sure they can fit a new value.
        /// Returns false for duplicate keys or insufficient resources.
        /// </summary>
        public void TryAddDocument(byte[] key, out int index)
        {
            index = 0;
            if (DocumentIdToIndex.TryGetValueInt32(key, ref index))
            {
                OnUpdateValueDocumentsKeyIndex(index);
                return;
            }

            // make a copy of the key (so that we don't introduce dependency on caller's local variables)
            // and reserve a new index value
            var newCount = Interlocked.Increment(ref m_untrimmedDocumentCount);

            if (newCount == int.MinValue)
            {
                // if we overflowed over max integer value, put max value back and throw
                Interlocked.CompareExchange(ref m_untrimmedDocumentCount, int.MaxValue, newCount);
                throw new Exception("Cannot expand storage any more");
            }

            index = newCount - 1;

            ExpandStorage(newCount);

            // now set values at the reserved index
            if (!DocumentKeys.TrySetAt(index, key))
            {
                throw new Exception("Failed to store new key value at " + index);
            }

            if (DocumentIdToIndex.TryAdd(DocumentKeys.GetIntPtrAt(index), index))
            {
                // mark document as valid, but don't touch any of its fields
                ValidDocumentsBitmap.SafeSet(index);
            }
            else
            {
                // seems like somebody slipped in and inserted the same value
                // mark our own generated index value as invalid
                ValidDocumentsBitmap.SafeClear(index);

                // now get "their" index and proceed to updating same record
                // some user data race is possible here, but container state won't be broken
                index = DocumentIdToIndex.GetInt32At(key);
            }
        }
        unsafe ExpandableArrayOfKeys GenerateKeys(ulong count)
        {
            var result = new ExpandableArrayOfKeys(_pool);
            result.EnsureCapacity(count);

            var key = new byte[10];

            for (ulong i = 1; i <= count; i++)
            {
                var val = i;
                byte pos = 1;
                while (val != 0)
                {
                    key[pos++] = (byte)val;
                    val >>= 8;
                }

                key[0] = (byte)(pos-1);

                //result[i-1] = key;
                if (!result.TrySetAt((int)i - 1, key))
                {
                    throw new Exception("Failed to set a key element at " + (i-1));
                }
            }

            for (ulong i = 1; i <= count; i++)
            {
                var storedKey = result.GetAt(i-1);

                var val = i;
                byte pos = 1;
                while (val != 0)
                {
                    key[pos++] = (byte)val;
                    val >>= 8;
                }

                key[0] = (byte)(pos-1);

                if (storedKey[0] != key[0])
                {
                    throw new Exception("Length prefix broken at " + (i - 1));
                }

                for (var j = 0; j <= key[0]; j++)
                {
                    //Console.Write(storedKey[j]);
                    //Console.Write(',');

                    if (storedKey[j] != key[j])
                    {
                        throw new Exception("Data broken at " + (i - 1) + ", offset " + j);
                    }
                }

                //Console.WriteLine();
            }

            return result;
        }
示例#3
0
        unsafe ExpandableArrayOfKeys GenerateKeys(ulong count)
        {
            var result = new ExpandableArrayOfKeys(_pool);

            result.EnsureCapacity(count);

            var key = new byte[10];

            for (ulong i = 1; i <= count; i++)
            {
                var  val = i;
                byte pos = 1;
                while (val != 0)
                {
                    key[pos++] = (byte)val;
                    val      >>= 8;
                }

                key[0] = (byte)(pos - 1);

                //result[i-1] = key;
                if (!result.TrySetAt((int)i - 1, key))
                {
                    throw new Exception("Failed to set a key element at " + (i - 1));
                }
            }

            for (ulong i = 1; i <= count; i++)
            {
                var storedKey = result.GetAt(i - 1);

                var  val = i;
                byte pos = 1;
                while (val != 0)
                {
                    key[pos++] = (byte)val;
                    val      >>= 8;
                }

                key[0] = (byte)(pos - 1);

                if (storedKey[0] != key[0])
                {
                    throw new Exception("Length prefix broken at " + (i - 1));
                }

                for (var j = 0; j <= key[0]; j++)
                {
                    //Console.Write(storedKey[j]);
                    //Console.Write(',');

                    if (storedKey[j] != key[j])
                    {
                        throw new Exception("Data broken at " + (i - 1) + ", offset " + j);
                    }
                }

                //Console.WriteLine();
            }


            return(result);
        }