Repository: microsoft/garnet
File: libs/server/Objects/List/ListObjectImpl.cs (C#)

Code before:

                var end = _input->done < 0 ? list.Count + _input->done : _input->done;
                if (end < -(list.Count - 1) || end >= list.Count) end = list.Count - 1;

                Debug.Assert(end - start <= list.Count);
                if (start > end)
                {
                    _output->opsDone = list.Count;
                    list.Clear();
                }
                else
                {
                    // Only  the first end+1 elements will remain
                    if (start == 0)
                    {
                        var numDeletes = list.Count - (end + 1);
                        for (int i = 0; i < numDeletes; i++)
                        {
                            var _value = list.Last.Value;
                            list.RemoveLast();
                            this.UpdateSize(_value, false);
                        }
                        _output->opsDone = numDeletes;
                    }
                    else
                    {
                        int i = 0;
                        IList<byte[]> readOnly = new List<byte[]>(list).AsReadOnly();
                        foreach (byte[] node in readOnly)
                        {
                            if (!(i >= start && i <= end))
                            {
                                list.Remove(node);
                                this.UpdateSize(node, false);
                            }
                            i++;
                        }
                        _output->opsDone = i;
                    }
                }
                _output->bytesDone = 0;
                _output->countDone = _output->opsDone;
            }
        }

        private void ListLength(byte* input, byte* output)
        {
            ((ObjectOutputHeader*)output)->countDone = list.Count;
        }

        private void ListPush(byte* input, int length, byte* output, bool fAddAtHead)

Review comment (performance):
Performance: Is this copy necessary? Can it iterate nodes via First..Next to the start then just remove nodes at that point? Possibly another PR to address

Code after:
                if (start > end || start >= list.Count || end < 0)
                {
                    outputHeader->opsDone = list.Count;
                    list.Clear();
                }
                else
                {
                    start = start < 0 ? 0 : start;
                    end = end >= list.Count ? list.Count : end + 1;

                    // Only  the first end elements will remain
                    if (start == 0)
                    {
                        var numDeletes = list.Count - end;
                        for (var i = 0; i < numDeletes; i++)
                        {
                            var value = list.Last!.Value;
                            list.RemoveLast();
                            this.UpdateSize(value, false);
                        }
                        outputHeader->opsDone = numDeletes;
                    }
                    else
                    {
                        var i = 0;
                        IList<byte[]> readOnly = new List<byte[]>(list).AsReadOnly();
                        foreach (var node in readOnly)
                        {
                            if (!(i >= start && i < end))
                            {
                                list.Remove(node);
                                this.UpdateSize(node, false);
                            }
                            i++;
                        }
                        outputHeader->opsDone = i;
                    }
                }

                outputHeader->bytesDone = 0;
                outputHeader->countDone = outputHeader->opsDone;
            }
        }

        private void ListLength(byte* input, byte* output)
        {
            ((ObjectOutputHeader*)output)->countDone = list.Count;
        }

        private void ListPush(byte* input, int length, byte* output, bool fAddAtHead)
        {