0

Here's what I want to do:

I have an arbitrary number of values of a different kind: string, int, float, bool, etc. that I need to store somehow. Multiple elements are often written and read as a whole, forming "contiguous blocks" that can also be extended and shortened at the users wish and even elements in the middle might be taken out. Also, the whole thing should be statically allocated.

I was thinking about using some kind of statically allocated forward lists. The way I imagine this to work is defining an array of a struct containing one std::variant field and a field "previous head" which always points to the location of the previous head of the list. A new element is always placed at the globally known "head" which it stores inside "previous head" field. This way I can keep track of holes inside my list because once an element is taken out, its location is written to global head and will be filled up by subsequent inserts.

This approach however has downsides: When a "contiguous block" is extended, there might be the case that further elements of other blocks have already queued up in the list past its last element. So I either need to move all subsequent entries or copy over the last element in the previous list and insert a link object that allows me to jump to the new location when traversing the contiguous block.

The priority to optimize this datastructure is following (by number of use cases):

  1. Initially write contigous blocks
  2. read the whole data structure
  3. add new elements to contigous blocks
  4. remove elements of contigous blocks

At the moment my data structure will have time complexity of O(1) für writes, O(n) for continous reads (with the caveat that in the worst case there is a jump to the next location inside the array every other element), O(1) for adding new elements and O(1) for removing elements. However, space complexity is S(2n) in the worst case (when I have to do a jump every second time the slot to store data is lost to the "link").

What I'm wondering now is: Is the described way the best viable way to accomplish what I'm trying or is there a better data structure? Is there an official name for this data structure?

glades
  • 3,778
  • 1
  • 12
  • 34
  • ' Multiple elements are often written and read at the same time, forming "contiguous blocks" ' Could you elaborate on this? How is concurrent r/w related to data storage? – Rinkesh P May 25 '22 at 06:49
  • If a 'node' in your data structure will hold only one of the many data types you listed, you might consider using a union – Rinkesh P May 25 '22 at 06:50
  • @RinkeshP: I'm using std::variant. Sorry I didn't mean concurrent reads or writes but reads and writes to a whole contiguous section inside the array. Edited my post – glades May 25 '22 at 06:53
  • you are using forward list while maintaining a rear pointer. I don't know much about c++ but from what I have read you can use `std::list` which is implemented as doubly linked list. – Rinkesh P May 25 '22 at 07:00
  • @RinkeshP std::list is dynamically allocating which is my problem. – glades May 25 '22 at 09:18
  • I think it is best not to use inbuilt data structures then. If I understood your problem correctly, you could create a struct containing next, previous and the data and statically allocate an array of them. Then you can manipulate it just as you manipulate a linked list, except now you will be working with indices(next, previous) instead of pointers. The only point where you will need to dynamically allocate more blocks is when you want to extend it. – Rinkesh P May 25 '22 at 09:31
  • @RinkeshP That was my solution so far. And its a datastructure that I stumple upon again and again. Does it not have a name? – glades May 25 '22 at 09:34
  • Well to me it just a linked list just implemented differently, since it supports all the operations of a linked list in same time complexities. – Rinkesh P May 25 '22 at 09:38

0 Answers0