Last active
December 29, 2019 01:26
-
-
Save pmttavara/7a63328ab07964f25ae4a8331bafa29c to your computer and use it in GitHub Desktop.
Virtual allocated array template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#define WIN32_LEAN_AND_MEAN | |
#define VC_EXTRALEAN | |
#include <windows.h> | |
template <class T> struct Virtual_Array { | |
T *data = nullptr; | |
unsigned int count = 0; | |
unsigned int allocated = 0; // Only stores 4 billion items, but that could easily be increased. | |
void reserve_bytes() { | |
data = (T *)VirtualAlloc(nullptr, sizeof(T) * 0x100000000, MEM_RESERVE, PAGE_NOACCESS); | |
//printf("Reserving %llu pages\n", sizeof(T) * 0x100000000 / 4096); | |
} | |
void commit_as_needed(unsigned int new_count) { | |
if (!data) { | |
reserve_bytes(); | |
} | |
if (allocated <= new_count) { | |
if (allocated < 1) allocated = 1; | |
do { | |
allocated *= 2; | |
} while (allocated <= new_count); | |
//printf("Committing %u items\n", allocated); | |
VirtualAlloc(data, allocated * sizeof(T), MEM_COMMIT, PAGE_READWRITE); | |
} | |
} | |
void release() { | |
VirtualFree(data, 0, MEM_RELEASE); | |
data = nullptr; | |
count = 0; | |
allocated = 0; | |
} | |
T &operator[](signed long long i) { | |
assert(i >= 0); | |
assert(i < count); | |
return data[(unsigned int)i]; | |
} | |
T *push(T value) { | |
assert(count < 0xffffffff); | |
commit_as_needed(count + 1); | |
T *result = &data[count]; | |
count += 1; | |
*result = value; | |
return result; | |
} | |
T *begin() { return data; } | |
T *end() { return data + count; } | |
}; | |
int main() { // WARNING, this test takes 8 gigs of ram, and a couple seconds to run. | |
Virtual_Array<Virtual_Array<int>> arrays; | |
for (int i = 0; i < 2; i += 1) { | |
Virtual_Array<int> dummy = {}; | |
arrays.push(dummy); | |
} | |
for (auto &&a : arrays) { | |
for (int i = 0; i < 1024 * 1024 * 1024; i += 1) { | |
a.push({i}); | |
} | |
//a.push({1024}); | |
printf("%d\n", a[rand() % a.count]); | |
} | |
for (auto &&a : arrays) a.release(); | |
arrays.release(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment