From 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 23 Nov 2016 19:09:09 +0900 Subject: Imported Upstream version 1.1.0 --- src/inc/gcinfoarraylist.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/inc/gcinfoarraylist.h (limited to 'src/inc/gcinfoarraylist.h') diff --git a/src/inc/gcinfoarraylist.h b/src/inc/gcinfoarraylist.h new file mode 100644 index 0000000000..c19f00d42f --- /dev/null +++ b/src/inc/gcinfoarraylist.h @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#ifndef _GCINFOARRAYLIST_H_ +#define _GCINFOARRAYLIST_H_ + +// GCInfoArrayList is basically a more efficient linked list--it's useful for accumulating +// lots of small fixed-size allocations into larger chunks which in a typical linked list +// would incur an unnecessarily high amount of overhead. + +class GcInfoArrayListBase +{ +private: + static const size_t GrowthFactor = 2; + +protected: + friend class IteratorBase; + + struct ChunkBase + { + ChunkBase* m_next; // actually GcInfoArrayListChunk* + }; + + class IteratorBase + { + protected: + IteratorBase(GcInfoArrayListBase* list, size_t firstChunkCapacity); + ChunkBase* GetNextChunk(size_t& elementCount); + + private: + GcInfoArrayListBase* m_list; + ChunkBase* m_currentChunk; + size_t m_currentChunkCount; + }; + + GcInfoArrayListBase(IAllocator* allocator); + virtual ~GcInfoArrayListBase(); + + void AppendNewChunk(size_t firstChunkCapacity, size_t elementSize, size_t chunkAlignment); + +public: + size_t Count() + { + return m_itemCount; + } + +protected: + IAllocator* m_allocator; + ChunkBase* m_firstChunk; // actually GcInfoArrayListChunk* + ChunkBase* m_lastChunk; // actually GcInfoArrayListChunk* + size_t m_lastChunkCount; + size_t m_lastChunkCapacity; + size_t m_itemCount; +}; + +template +class GcInfoArrayList : public GcInfoArrayListBase +{ +private: + struct Chunk : public ChunkBase + { + ElementType m_items[]; + }; + +public: + friend class Iterator; + + struct Iterator : IteratorBase + { + Iterator(GcInfoArrayList* list) + : IteratorBase(list, FirstChunkCapacity) + { + } + + ElementType* GetNext(size_t* elementCount) + { + Chunk* chunk = reinterpret_cast(GetNextChunk(*elementCount)); + return chunk == nullptr ? nullptr : &chunk->m_items[0]; + } + }; + + GcInfoArrayList(IAllocator* allocator) + : GcInfoArrayListBase(allocator) + { + } + + ElementType* Append() + { + if (m_lastChunk == nullptr || m_lastChunkCount == m_lastChunkCapacity) + { + AppendNewChunk(FirstChunkCapacity, sizeof(ElementType), __alignof(ElementType)); + } + + m_itemCount++; + m_lastChunkCount++; + return &reinterpret_cast(m_lastChunk)->m_items[m_lastChunkCount - 1]; + } + + void CopyTo(ElementType* dest) + { + Iterator iter(this); + ElementType* source; + size_t elementCount; + + while (source = iter.GetNext(&elementCount), source != nullptr) + { + memcpy(dest, source, elementCount * sizeof(ElementType)); + dest += elementCount; + } + } +}; + +#endif -- cgit v1.2.3