GÜNCELLEME: Bu soru blogumun 8 Haziran 2012 tarihli konusuydu . Bu mükemmel soru için teşekkürler!
Harika soru. Ortaya koyduğunuz konuları çok uzun süre tartıştık.
Aşağıdaki özelliklere sahip bir veri yapısına sahip olmak istiyoruz:
- Immutable.
- Bir ağacın şekli.
- Alt düğümlerden üst düğümlere ucuz erişim.
- Ağaçtaki bir düğümden metindeki bir karakter ofsetine eşlemek mümkündür.
- Kalıcı .
By kalıcılık I yeteneği anlamına ağacında mevcut düğümlerin çoğunu yeniden bir düzenleme metin tamponuna yapıldığında. Düğümler değişmez olduğundan, onları yeniden kullanmanın önünde bir engel yoktur. Performans için buna ihtiyacımız var; Bir tuşa her bastığınızda dosyanın büyük kısımlarını yeniden ayrıştıramayız. Ağacın yalnızca düzenlemeden etkilenen kısımlarını yeniden tanımlamalı ve yeniden ayrıştırmalıyız.
Şimdi bunların beşini tek bir veri yapısına koymaya çalıştığınızda hemen sorunlarla karşılaşırsınız:
- İlk etapta nasıl bir düğüm oluşturursunuz? Ebeveyn ve çocuk, her ikisi de birbirlerine atıfta bulunur ve değişmezdir, öyleyse hangisi önce inşa edilir?
- Bu sorunu çözmeyi başardığınızı varsayarsak: nasıl kalıcı hale getirirsiniz? Bir alt düğümü farklı bir ebeveynde yeniden kullanamazsınız çünkü bu, çocuğa yeni bir ebeveyni olduğunu söylemeyi içerir. Ancak çocuk değişmezdir.
- Bu sorunu çözmeyi başardığınızı varsayarsak: düzenleme arabelleğine yeni bir karakter eklediğinizde, o noktadan sonra bir konuma eşlenen her düğümün mutlak konumu değişir. Bu, kalıcı bir veri yapısı oluşturmayı çok zorlaştırır, çünkü herhangi bir düzenleme, düğümlerin çoğunun kapsamını değiştirebilir!
Ancak Roslyn ekibinde rutin olarak imkansız şeyler yapıyoruz. Aslında imkansız olanı iki ayrıştırma ağacını tutarak yapıyoruz . "Yeşil" ağaç değişmez, kalıcıdır, üst referansları yoktur, "aşağıdan yukarıya" oluşturulmuştur ve her düğüm genişliğini izler ancak mutlak konumunu takip etmez . Bir düzenleme gerçekleştiğinde, yeşil ağacın yalnızca düzenlemeden etkilenen kısımlarını yeniden oluştururuz, bu tipik olarak ağaçtaki toplam ayrıştırma düğümlerinin yaklaşık O (log n) kadarıdır.
"Kırmızı" ağaç bir değişmez cephe yeşil ağacın etrafında inşa edilmiştir; istek üzerine "yukarıdan aşağıya" oluşturulur ve her düzenlemede atılır. Siz ağaçtan yukarıdan aşağıya inerken talep üzerine bunları üreterek ana referansları hesaplar . Siz aşağı indikçe yine genişliklerden hesaplayarak mutlak konumları üretir.
Siz, kullanıcı, yalnızca kırmızı ağacı görürsünüz; yeşil ağaç bir uygulama detayıdır. Bir ayrıştırma düğümünün dahili durumuna bakarsanız, aslında orada farklı türde başka bir ayrıştırma düğümüne bir referans olduğunu görürsünüz ; bu yeşil ağaç düğümüdür.
Bu arada, bunlara "kırmızı / yeşil ağaçlar" denir çünkü bunlar, tasarım toplantısında veri yapısını çizmek için kullandığımız beyaz tahta kalemi renkleriydi. Renklerin başka bir anlamı yok.
Bu stratejinin yararı, tüm bu harika şeyleri elde etmemizdir: değişmezlik, kalıcılık, ebeveyn referansları vb. Maliyet, bu sistemin karmaşık olması ve "kırmızı" cepheler büyürse çok fazla bellek tüketebilmesidir. Şu anda, bazı maliyetleri, faydalarını kaybetmeden düşürüp azaltamayacağımızı görmek için deneyler yapıyoruz.