Example #1
0
        public void Add(long id, BlittableJsonReaderObject result)
        {
            IsModified = true;

            using (_env.GetTemporaryPage(_parent.Llt, out TemporaryPage tmp))
            {
                var dataPosInTempPage = 0;
                var readResult        = _parent.Read(_nestedValueKey);
                if (readResult != null)
                {
                    var reader = readResult.Reader;
                    var entry  = (ResultHeader *)reader.Base;
                    var end    = reader.Base + reader.Length;
                    while (entry < end)
                    {
                        if (entry->Id == id)
                        {
                            if (entry->Size != result.Size)
                            {
                                Delete(id);
                                readResult = _parent.Read(_nestedValueKey);
                                break;
                            }
                            using (_parent.DirectAdd(_nestedValueKey, reader.Length, out byte *ptr))
                            {
                                var pos = ptr + ((byte *)entry - reader.Base + sizeof(ResultHeader));
                                Memory.Copy(pos, result.BasePointer, result.Size);
                                return;// just overwrite it completely
                            }
                        }
                        entry = (ResultHeader *)((byte *)entry + sizeof(ResultHeader) + entry->Size);
                    }

                    if (readResult != null)
                    {
                        Memory.Copy(tmp.TempPagePointer, readResult.Reader.Base, readResult.Reader.Length);
                        dataPosInTempPage = readResult.Reader.Length;
                    }
                }

                Debug.Assert(dataPosInTempPage + sizeof(ResultHeader) + result.Size <= tmp.TempPageBuffer.Length);
                var newEntry = (ResultHeader *)(tmp.TempPagePointer + dataPosInTempPage);
                newEntry->Id   = id;
                newEntry->Size = (ushort)result.Size;
                Memory.Copy(tmp.TempPagePointer + dataPosInTempPage + sizeof(ResultHeader), result.BasePointer, result.Size);
                dataPosInTempPage += result.Size + sizeof(ResultHeader);
                using (_parent.DirectAdd(_nestedValueKey, dataPosInTempPage, out byte *destPtr))
                    Memory.Copy(destPtr, tmp.TempPagePointer, dataPosInTempPage);

                _dataSize += result.Size + sizeof(ResultHeader);
            }
        }