Strona głównaArtykułyTablica części: Tajemniczy bufor edytora tekstu

Tablica części: Tajemniczy bufor edytora tekstu

Każda naciskana klawisza w edytorze tekstowym musi aktualizować dokument somehow, a proste podejście polegające na przechowywaniu całego dokumentu jako jedno duży mutowalne string szybko okazuje się nieefektywne: wstawienie pojedynczego znaku w środku pliku zawierającego milion znaków oznacza przesunięcie wszystkiego co po nim, operacja O(n) na każdym naciśnięciu klawisza, która sprawia, że duże dokumenty wydają się wolne. Tablica części jest eleganckim rozwiązaniem dla tego problemu, używana w produkcyjnych edytorach, w tym w wcześniejszych wersjach Microsoft Word i najnowszej jako podstawowa struktura danych dla bufora tekstowego VS Code. Zamiast przechowywać dokument jako jedno mutowalne obiekt, tablica części przechowuje dwa tylko do zapisu bufora: oryginalny bufor przechowujący zawartość pliku dokładnie jak załadowana, oraz add buffer rosnący przez dodawanie każdego nowego znaku wprowadzanego przez użytkownika, a nie modyfikuje ani zapisuje żadnego z nich na miejscu. Dokument rzeczywisty jest reprezentowany pośrednio jako uporządkowana sekwencja małych opisów nazywanych częściami, każda z której to prosty wskaźnik do jednego z dwóch buforów, wraz z przesunięciem początkowym i długością, opisując ciąg znaków. Edycja dokumentu staje się operacją na tej lekkostrukturalnej sekwencji opisów, a nie bezpośrednio na tekście: wstawianie tekstu dzieli istniejącą część na dwie i wprowadza nową część wskaźnikową do nowo dodanego treść add-buffera, podczas gdy usuwanie tekstu analogicznie dzieli i skróca części bez dotykania podstawowych buforów. Ta symulacja pozwala Ci pisać i usuwać w żywej tablicy części, obserwując aktualne zaktualizowanie bufora oryginalnego, add buffera oraz listy węzłów opisujących części w czasie rzeczywistym.

mysimulator teamZaktualizowano — czerwiec 2026≈ 8 min czytania▶ Otwórz symulację

Dwa buforzy, nigdy nie modyfikowane miejsce

Oryginalny bufor jest wczytywany tylko raz podczas otwierania pliku i traktowany jako całkowicie odczytowy przez całą sesję edycji; nic nigdy nie jest wstawiane ani uszczuplanie z tego buferra. Bufor dodawania jest pusty na początku i rosnie jedynie poprzez dopisywanie, każdy znak wprowadzony przez użytkownika gdziekolwiek w dokumencie zostaje dołączany do końca tego buforza, niezależnie od miejsca, w którym powinien się pojawiać w lini logicznej dokumentu. Ta dyscyplina dopisywania jedynie jest to, co sprawia, że tablica części jest efektywna: ponieważ żaden z buferrów nigdy nie jest modyfikowany w trakcie, nie ma potrzeby drogiego przesuwania pamięci przy obsługi edycji, a oba buforzy mogą być zaimplementowane jako proste, ciągłe, rosnące tablice, które są bardzo przyjazne dla bufora podręcznego i szybkie do dopisywania. Faktyczna wizualna pozycja znaku w dokumencie jest całkowicie wyznaczona przez miejsce, w którym znajduje się opisujący go fragment w sekwencji fragmentów, a nie przez jego fizyczny offset w żadnym z buferrów, co to koncepcyjne przesunięcie, które oddziela porządek logiczny dokumentu od porządku przechowywania fizycznego.

Sekwencja części: uporządkowana lista małych opisów

Dokument jest reprezentowany jako uporządkowana sekwencja opisów części, zazwyczaj implementowana jako podwójnie wskazana lista lub rzadko struktura zaawansowana jak drzewo 균형잡힌 dla bardzo dużych dokumentów. Każda część to mały krotka zapisująca, do którego buforu wskazuje, od jakiego offseta w tym buforze się zaczyna i długość zakresu tekstu, który pokrywa. Czytanie całego dokumentu w porządku oznacza proste przejście po tej sekwencji od początku do końca i łączenie tekstów odwołanych przez każdą część; nowo otwarty, nieedytowany plik zaczyna się jako pojedyncza część obejmująca całe oryginalne bufor. Ponieważ części są małymi ustalonej wielkości rekordami zamiast kopiami rzeczywistego tekstu, sekwencja części pozostaje skompaktowana nawet dla bardzo edytowanego dokumentu, rosnąc tylko w proporcji do liczby operacji edycji wykonywanych, a nie wielkości dokumentu ani ilości wstawianego tekstu, co jest kluczowym rozróżnieniem od podejść wymagających kopiowania zakresów tekstowych przy każdym zmianie.

Wstawianie tekstu: rozdzielanie i łączenie

Aby wstawić nowy tekst na pewnej pozycji w dokumencie, edytor najpierw dopisuje nowo wprowadzone znaki do końca bufora dodatkowego, a następnie znajduje, który z istniejących elementów w sekwencji obecnie pokrywa tę pozycję wstawienia. Jeśli punkt wstawienia spadł dokładnie na granicę elementu, można prosto dodać nowy element opisujący nowo dopisaną tekst do listy łączonych elementów bez dodatkowych operacji. Jeśli punkt wstawienia znajduje się w środku istniejącego elementu, ten element musi zostać podzielony na dwa elementy: jeden pokrywający tekst przed punktem wstawienia i drugi pokrywający tekst po nim, oba nadal łączące się z tym samym oryginalnym buforom, a nowy element dla wprowadzonego tekstu jest wstawiany między nimi. W każdym przypadku ta operacja dotyczy tylko małej stałej liczby opisów elementów, dzieląc najwyżej jeden istniejący element i wstawiając jeden nowy element, niezależnie od wielkości dokumentu, co sprawia, że wprowadzanie tekstu do edytora opartego na tablicie elementów pozostaje szybkie nawet dla dokumentów zawierających miliony znaków.

Usuwanie tekstu: podział i skróty, bez utraty danych

Usunięcie działa na tle tej samej logiki podziału i splicing w odwrotnej kolejności. Jeśli zakres usuniętego tekstu dokładnie pokrywa jedno lub więcej pełnych elementów, te elementy są prosto usuwane z sekwencji. Jeśli zakres usuniętego tekstu zaczyna się lub kończy w środku elementu, ten element jest podzielony na granicy usunięcia, a tylko część poza zakresem usunięcia jest zachowana w sekwencji; część spadająca wewnątrz zakresu usunięcia prosto jest wykluczona z listy elementów dalej, nawet jeśli podstawowe bajty nadal fizycznie istnieją i nie są modyfikowane ani zmniejszone. To jedna z najpiękniejszych cech tabeli elementów: ponieważ podstawowe bufora nigdy naprawdę nie są modyfikowane ani zmniejszane, usunięty tekst nigdy naprawdę nie jest zniszczony, tylko po prostu już nie jest odwoływany przez żaden element w bieżącej sekwencji, co oznacza, że struktura danych naturalnie toleruje projekt, który chce zachować stare teksty dla innych celów.

Szybkie i ekonomiczne cofanie się i ponowne wykonywanie bez dodatkowych kosztów

Dzięki temu, że każda operacja edycji jest wyrażona jako mała, lokalna zmiana w sekwencji elementów, redaktor może zaimplementować pełny mechanizm cofania się i ponownego wykonywania poprzez zapisanie, dla każdej operacji edycji, które elementy zostały usunięte oraz które dodane, podstawowo małą różnicę listy skojarzonej, a nie różnicę lub kopię pełnego tekstu dokumentu. Cofnięcie wstecz dodania oznacza usunięcie tych samych elementów, które były dodane, i przywrócenie tych, które zostały podzielone, bez zmiany żadnej z pamięci buforowych, a ponowne wykonywanie prosto powtarza tę małą zmianę. To znacznie jest mniej kosztowne niż banalne implementacje cofania się, które tworzą kopię pełnego tekstu dokumentu na każdym naciśnięciu klawisza, i to jest jednym z głównych powodów, dla których tablice elementów nadal pozostają popularne w nowoczesnych implementacjach edytorów: daje im nie tylko szybkie pisanie, ale także prawie bezpłatną, ekonomiczną historię cofania się jako naturalny efekt tego, jak edycje są już reprezentowane wewnętrznie, co jest dokładnie takim rodzajem projektu, że poprawna implementacja struktury danych zapewnia korzyści na całym pozostałym systemie.

Często zadawane pytania

Dlaczego nie można użyć jednej mutowalnej napisu lub tablicy dla całego dokumentu?

Wstawianie lub usuwanie w środku dużej mutowalnej tablicy wymaga przesunięcia każdego znaku po punkcie edycji, co prowadzi do kosztu O(n) na klawisz, który staje się wyraźnie wolny dla dużych plików. Tablice części unikają tego, ponieważ nigdy nie przesuwają istniejącego tekstu, tylko dostosowują małe opisy.

Co dokładnie jest przechowywane w opisie części?

Opis części zapisuje, który bufor, oryginalny lub dodany, wskazany przez część, offset początkowy w tym buforze oraz długość zakresu tekstu, którego on pokrywa. Nie zawiera on żadnych rzeczywistych znaków, tylko metadanych opisujących zakres.

Czy usuwanie tekstu kiedykolwiek naprawdę usuwa bajty z pamięci?

Nie. Usuwanie polega jedynie na usunięciu lub skróceniu opisów części w sekwencji, tak że usunięty tekst już nie jest częścią widocznej dokumentacji; podstawowe bajty pozostają fizycznie obecne w oryginalnym lub dodanym buforze, po prostu niewykorzystane.

Jak tablica części sprawia, że cofnięcie i ponowne wykonanie są efektywne?

Bo każda edycja to tylko mała, lokalna zmiana w sekwencji części, np. podział jednej części na dwie lub splicing nowej, co pozwala cofnięciu tylko zapisywać i odwracać tę małą zmianę zamiast zrzut dokumentu, co sprawia, że historia cofnięcia jest ekonomiczna do utrzymania.

Jakie rzeczywiste edytory używają tablic części?

Dawne wersje Word'a Microsofta używały podejścia opartego na tablicach części, a implementacja podstawowego buforu tekstowego VS Code, opisana w jej blogu technicznym, używa variantu tablicy części opartego na drzewie równoważnym do efektywnego edytowania dużych plików.

Wypróbuj na żywo

Wszystko powyżej działa bezpośrednio w Twojej przeglądarce — otwórz Piece Table: The Text Editor's Secret Edit Buffer i zmieniaj parametry podczas działania. Nic nie jest instalowane ani przesyłane na serwer, cały model działa w jednej karcie.

▶ Otwórz symulację Piece Table: The Text Editor's Secret Edit Buffer

Co znalazłeś?

Dodaj kroki odtworzenia (opcjonalnie)