/// <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; }
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); }