Ręcznie
Jeśli pamięć nie jest bardzo rzadkim zasobem, rozważam pracę w większych porcjach.
Oto pseudo-kod.
class Chunk {
Chunk new(int size) {...}
void setPixel(int x, int y, int value) {...}
int getPixel(int x, int y) {...}
}
class Grid {
Map<int, Map<Chunk>> chunks;
Grid new(int chunkSize) {...}
void setPixel(int x, int y, int value) {
getChunk(x,y).setPixel(x % chunkSize, y % chunkSize, value);//actually the modulo could be right in Chunk::setPixel and getPixel for more safety
}
int getPixel(int x, int y) { /*along the lines of setPixel*/ }
private Chunk getChunk(int x, int y) {
x /= chunkSize;
y /= chunkSize;
Map<Chunk> row = chunks.get(y);
if (row == null) chunks.set(y, row = new Map<Chunk>());
Chunk ret = row.get(x);
if (ret == null) row.set(x, ret = new Chunk(chunkSize));
return ret;
}
}
Ta implementacja jest dość naiwna.
Po pierwsze, tworzy porcje w getPixel (w zasadzie dobrze byłoby po prostu zwrócić 0 lub mniej, jeśli dla tej pozycji nie zdefiniowano żadnych porcji). Po drugie, opiera się na założeniu, że masz wystarczająco szybką i skalowalną implementację Map. O ile mi wiadomo, każdy przyzwoity język ma jeden.
Będziesz także musiał grać z rozmiarem porcji. W przypadku gęstych bitmap duży rozmiar fragmentu jest dobry, a dla rzadkich bitmap lepszy rozmiar mniejszego fragmentu. W rzeczywistości w przypadku bardzo rzadkich „wielkość porcji” 1 jest najlepsza, co powoduje, że same „porcje” stają się przestarzałe i redukuje strukturę danych do int mapy int mapy pikseli.
Z półki
Innym rozwiązaniem może być przeglądanie niektórych bibliotek graficznych. Są naprawdę całkiem dobrzy w rysowaniu jednego bufora 2D w innym. Oznaczałoby to, że po prostu przydzielisz większy bufor i wciągniesz do niego oryginał o odpowiednich współrzędnych.
Jako ogólna strategia: mając „dynamicznie rosnący blok pamięci”, dobrym pomysłem jest przydzielenie jego wielokrotności po zużyciu. Jest to dość obciążające pamięć, ale znacznie obniża koszty alokacji i kopiowania . Większość implementacji wektorowych przydziela dwukrotnie ich rozmiar, gdy zostanie przekroczony. Dlatego szczególnie, jeśli korzystasz z gotowego rozwiązania, nie rozszerzaj bufora tylko o 1 piksel, ponieważ zażądano tylko jednego piksela. Przydzielona pamięć jest tania. Ponowne przydzielanie, kopiowanie i wydawanie jest kosztowne.