Istnieje opublikowane rozwiązanie tego problemu z bardzo dobrą zamortyzowaną złożonością czasu, ale trudno je znaleźć, gdy nie wiesz dokładnie, czego szukać. Ładne podsumowanie można znaleźć w tych notatkach z wykładów (zob. Sekcja 2.2.3) lub przeczytać oryginalny artykuł Tworzenie trwałych struktur danych . Jeśli twój wykres obiektowy ma ograniczoną łączność (np. Struktury drzewiaste), możesz nawet osiągnąć zamortyzowaną złożoność O (1) zarówno dla odczytu, jak i aktualizacji niezmiennego wykresu, co jest imponujące.
Chodzi o to, że każdy obiekt oprócz przechowywania swojego obecnego niezmiennego stanu, rezerwuje miejsce na rejestrowanie zmian. Jeśli chcesz utworzyć nowy niezmienny wykres z istniejącego poprzez zastosowanie zmian, musisz wziąć pod uwagę dwa przypadki:
Obiekt, który chcesz zmienić, ma jeszcze miejsce na zmiany. Możesz przechowywać zmiany bezpośrednio w obiekcie.
W obiekcie nie ma już miejsca na zmiany. Tworzysz nowe wystąpienie na podstawie bieżących wartości i pustych rekordów zmian. Teraz musisz rekurencyjnie aktualizować wszystkie obiekty odwołujące się do starego obiektu, aby odwoływały się do nowego obiektu.
Jeśli w samym obiekcie odniesienia jest jeszcze miejsce na zmiany, można zapisać zmianę w odwołaniu bezpośrednio, w przeciwnym razie nastąpi ona kaskadowo.
Chociaż ten schemat obsługuje wydajne tworzenie nowych generacji niezmiennych wykresów obiektów, komplikuje czytanie z niego, ponieważ teraz musisz określić, do której „wersji” chcesz uzyskać dostęp podczas odczytywania danych z niezmiennego obiektu. Wynika to z faktu, że niezmienny obiekt może zawierać informacje dla wielu wersji z powodu zapisanych zapisów zmian, dlatego musisz określić, którą wersję chcesz obejrzeć.
Podczas implementacji staram się ukryć tę złożoność w interfejsie API. Odnosząc się do czegoś na niezmiennym wykresie z zewnątrz, używam wygenerowanych kodów pośredniczących zamiast bezpośrednich odniesień, więc osoby dzwoniące nie muszą ręcznie przekazywać żądanej wersji. To sprawia, że referencje są nieco droższe niż bezpośredni wskaźnik, ale uważam, że jest to warte wygody.