---
title: 'Anlık Görüntü ve Geri Yükleme'
source: 'https://academia.sh/tr/kurslar/arama-motorlari/anlik-goruntu-ve-geri-yukleme'
course: 'Arama Motorları ve Metin Erişimi'
language: tr
updated: '2026-08-17T18:09:01+00:00'
license: 'CC BY-SA 4.0'
---

# Anlık Görüntü ve Geri Yükleme

Dizine özgü yedekleme kararı: bölütlerin değişmezliği üzerine kurulan artımlı anlık görüntünün kopyaladığı bayt, arka plan birleştirmesinin artımlılığı bozması, depoda tutulanın canlı dizinden büyük olması ve geri yükleme ile kaynaktan yeniden dizinlemenin kopyalanan bayt, işlenen belge, küme ile sıra üzerinden karşılaştırılması.

Devretme, eski veriden kurtulmayı dosya düşürmeye indirdi. Aynı yapı yedeklemeyi de değiştirir:
yazıldıktan sonra bir daha değişmeyen bölütler, yedeklenecek şeyi "durmadan değişen bir durum"
olmaktan çıkarıp **değişmez dosyalardan oluşan bir kümeye** çevirir.

Bellek içi bir deponun anlık görüntüsü daha önce ölçüldü: aralık ile kayıp penceresi arasındaki
ilişki, görüntü almanın çalışan depoya maliyeti. O ölçüm burada tekrarlanmaz. Buranın sorusu
dizine özgüdür. Bölütler değişmezse görüntü **artımlı** olabilir; peki arka planda çalışan
birleştirme buna ne yapar, ve dizin geri gelmesi gerektiğinde onu depodan taşımak mı yoksa
kaynaktan **yeniden dizinlemek** mi daha ucuzdur.

## Bölüt Düzeyinde Görüntü

**AK18.** Bölüt dosyası adıyla birlikte değişmezdir: depoda belirli bir ada sahip dosya her
zaman aynı içeriği taşır. Artımlı görüntü bunun üzerine kurulur — depoda o ad varsa dosya
yeniden kopyalanmaz.

**AK19.** Görüntünün bedeli kopyalanan bayttır; depoda tutulan, birbirinden farklı bölüt
dosyalarının toplamıdır.

**AK20.** Yeniden dizinleme kaynak kayıtların elde olduğunu, aynı günlük partilerin ve aynı
birleştirme politikasının uygulandığını varsayar. Süre koşum ortamına bağlıdır ve bu yüzden
basılmaz; onun yerine koşumdan bağımsız iki nicelik sayılır: kopyalanan bayt ile işlenen belge
ve belirteç.

Derlem 8.000 kitap kaydıdır, tohum 20260731.

```js
// yedek.mjs — katalog derlemi, çözümleyiciler, bölütlü dizin ve bölüt düzeyinde görüntü deposu
import { writeFileSync, existsSync, mkdirSync, statSync } from 'node:fs';

export function uretec(tohum) {               // belirlenimci sözde rastgele üreteç
  let a = tohum >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

const SIFAT = 'sessiz uzak kırık yitik beyaz kara ince derin sarı uzun'.split(' ');
const ADLAR = 'kapı deniz yol ev şehir bahçe ada defter ırmak kuyu'.split(' ');
const KONU = ('çocuk edebiyatı|kısa öykü|roman|deneme|şiir|tarih|coğrafya|felsefe|psikoloji|' +
  'ekonomi|mimarlık|müzik|sinema|gezi|biyografi|anı|bilim kurgu|polisiye|halk bilimi').split('|');
const KOK = ('kitap yazar anlatı öykü çocuk kent bellek yolculuk kuşak savaş göç aile deniz kış ' +
  'sabah mektup fotoğraf tren sokak okul kütüphane rüzgâr sessizlik umut ada yağmur orman köy ' +
  'dağ nehir sınır yüzyıl kadın asker öğretmen hekim ressam şarkı dize kapak').split(' ');
const DOLGU = 've ile bir ya'.split(' ');

function cekim(kok, i) {                      // ek yüzey biçimi: ünlü uyumu ve sertleşme
  const v = [...kok].reverse().find((c) => 'aeıioöuü'.includes(c));
  const k = 'aıou'.includes(v), d = 'fhkpsştç'.includes(kok.at(-1)) ? 't' : 'd';
  return kok + ['', k ? 'lar' : 'ler', d + (k ? 'a' : 'e'), d + (k ? 'an' : 'en'), k ? 'la' : 'le',
    k ? 'lara' : 'lere', k ? 'larda' : 'lerde', k ? 'lardan' : 'lerden'][i];
}

export function derlemUret(sayi, tohum) {
  const r = uretec(tohum), liste = [];
  for (let i = 0; i < sayi; i++) {
    const ozet = [];
    for (let j = 0; j < 16; j++)
      ozet.push(j % 4 === 3 ? DOLGU[Math.floor(r() * 4)]
        : cekim(KOK[Math.floor(r() ** 2 * KOK.length)], Math.floor(r() ** 2 * 8)));
    liste.push({ id: 'k' + String(i).padStart(5, '0'),
      ad: `${SIFAT[Math.floor(r() * 10)]} ${ADLAR[Math.floor(r() * 10)]}`,
      ozet: ozet.join(' '), konu: KONU[Math.floor(r() * 19)] });
  }
  return liste;
}

export const metin = (b) => `${b.ad} ${b.ozet} ${b.konu}`;

const DURAK = new Set(DOLGU);
const EK = ['lardan', 'lerden', 'larda', 'lerde', 'lara', 'lere', 'lar', 'ler', 'dan', 'den',
  'tan', 'ten', 'da', 'de', 'ta', 'te', 'la', 'le'];
const kok = (t) => {                          // kök bulma: en uzun eşleşen eki kırpar
  for (const e of EK) if (t.length > e.length + 2 && t.endsWith(e)) return t.slice(0, -e.length);
  return t;
};
export const temel = (s) =>                   // küçük harf + harf dışı ayırıcı
  s.toLocaleLowerCase('tr').split(/[^\p{L}\p{N}]+/u).filter((t) => t.length > 1);
export const gelismis = (s) =>                // + durak sözcük atma + kök bulma
  temel(s).filter((t) => !DURAK.has(t)).map(kok);

let sayac = 0;
export class Bolut {                          // adı içeriğiyle birlikte sabittir: bir daha yazılmaz
  constructor(belgeler = [], coz = temel) {
    this.ad = 'b' + String(++sayac).padStart(3, '0');
    this.sozluk = new Map(); this.belge = new Set();
    for (const b of belgeler) {
      this.belge.add(b.id);
      const sayim = new Map();
      for (const t of coz(metin(b))) sayim.set(t, (sayim.get(t) || 0) + 1);
      for (const [t, tf] of sayim) {
        if (!this.sozluk.has(t)) this.sozluk.set(t, []);
        this.sozluk.get(t).push([b.id, tf]);
      }
    }
  }
  serile() {
    let s = '';
    for (const [t, g] of this.sozluk) s += t + '\t' + g.map(([i, f]) => i + ':' + f).join(' ') + '\n';
    return s;
  }
  get bayt() { return Buffer.byteLength(this.serile()); }
}

export function yigin(carpan = 4) {           // katmanlı birleştirme yığını
  const katman = [];
  let birlestirme = 0;
  const yerlestir = (b, k) => {
    while (katman.length <= k) katman.push([]);
    katman[k].push(b);
    if (katman[k].length < carpan) return;
    birlestirme++;
    yerlestir(birlestir(katman[k].splice(0, carpan)), k + 1);
  };
  return {
    ekle(belgeler, coz) { birlestirme = 0; yerlestir(new Bolut(belgeler, coz), 0); },
    get bolutler() { return katman.flat(); },
    get birlestirme() { return birlestirme; },
  };
}

export function birlestir(grup) {
  const y = new Bolut();
  for (const bl of grup) {
    for (const id of bl.belge) y.belge.add(id);
    for (const [t, g] of bl.sozluk) {
      if (!y.sozluk.has(t)) y.sozluk.set(t, []);
      for (const p of g) y.sozluk.get(t).push(p);
    }
  }
  return y;
}

export function ara(bolutler, terimler, k = 10) {
  const puan = new Map();
  for (const bl of bolutler) {
    const N = bl.belge.size;
    for (const t of terimler) {
      const g = bl.sozluk.get(t);
      if (!g) continue;
      const idf = Math.log(1 + N / g.length);
      for (const [id, tf] of g) puan.set(id, (puan.get(id) || 0) + tf * idf);
    }
  }
  const sira = [...puan].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1));
  return { ilkK: sira.slice(0, k).map(([id]) => id), eslesen: sira.length };
}

// görüntü: bölüt dosyası depoda yoksa yazılır; artımlı olmayan görüntü hepsini yeniden yazar
export function goruntuAl(bolutler, depo, artimli) {
  mkdirSync(depo, { recursive: true });
  let kopyalanan = 0, dosya = 0;
  for (const b of bolutler) {
    const yol = `${depo}/${b.ad}`;
    if (artimli && existsSync(yol)) continue;
    writeFileSync(yol, b.serile());
    kopyalanan += statSync(yol).size; dosya++;
  }
  return { kopyalanan, dosya, liste: bolutler.map((b) => b.ad) };
}
```

## Artımlı Görüntü ve Birleştirmenin Bozduğu

Katalog on altı gün boyunca günde 500 kayıt alır ve her günün sonunda bir görüntü alınır. Aynı
gün iki kez ölçülür: dizinin tamamını kopyalayan tam görüntü ve yalnız depoda bulunmayan bölüt
dosyalarını kopyalayan artımlı görüntü.

```js
// goruntu.mjs — on altı günlük dizinde tam ve artımlı anlık görüntünün kopyaladığı bayt
import { derlemUret, yigin, goruntuAl } from './yedek.mjs';

const derlem = derlemUret(8000, 20260731);
const y = yigin(4);
console.log('derlem: 8000 belge, tohum 20260731 | günde 500 belgelik bir toplu iş, çarpan 4');
console.log('gün  bölüt  birleştirme  tam görüntü bayt  artımlı bayt  artımlı dosya  depoda tutulan');
let tamToplam = 0, depoBayt = 0;
for (let gun = 1; gun <= 16; gun++) {
  y.ekle(derlem.slice((gun - 1) * 500, gun * 500));
  const tam = goruntuAl(y.bolutler, `tam/g${gun}`, false);
  const art = goruntuAl(y.bolutler, 'depo', true);
  tamToplam += tam.kopyalanan; depoBayt += art.kopyalanan;
  console.log(String(gun).padStart(3), String(y.bolutler.length).padStart(6),
    String(y.birlestirme).padStart(12), String(tam.kopyalanan).padStart(17),
    String(art.kopyalanan).padStart(13), String(art.dosya).padStart(14),
    String(depoBayt).padStart(15));
}
console.log('toplam: tam görüntüler', tamToplam, 'bayt, artımlı görüntüler', depoBayt, 'bayt');
```

```
derlem: 8000 belge, tohum 20260731 | günde 500 belgelik bir toplu iş, çarpan 4
gün  bölüt  birleştirme  tam görüntü bayt  artımlı bayt  artımlı dosya  depoda tutulan
  1      1            0             81694         81694              1           81694
  2      2            0            162974         81280              1          162974
  3      3            0            244317         81343              1          244317
  4      1            1            315289        315289              1          559606
  5      2            0            397163         81874              1          641480
  6      3            0            478662         81499              1          722979
  7      4            0            560200         81538              1          804517
  8      2            1            631586        316297              1         1120814
  9      3            0            713127         81541              1         1202355
 10      4            0            794677         81550              1         1283905
 11      5            0            876578         81901              1         1365806
 12      3            1            947640        316054              1         1681860
 13      4            0           1029181         81541              1         1763401
 14      5            0           1111100         81919              1         1845320
 15      6            0           1192704         81604              1         1926924
 16      1            2           1253638       1253638              1         3180562
toplam: tam görüntüler 10790530 bayt, artımlı görüntüler 3180562 bayt
```

Birleştirme olmayan günlerde artımlı görüntü sabit bir bedel öder: yaklaşık 81.500 bayt, yani
o gün eklenen tek bölüt. Tam görüntü ise her gün bütün dizini kopyalar ve on beşinci günde tek
bir yedek 1.192.704 bayta çıkar. On altı günün toplamında fark on kata yakındır: 10.790.530
bayta karşılık 3.180.562 bayt.

Kritik satırlar 4, 8, 12 ve 16. numaralı günlerdir. Birleştirmenin çalıştığı günde artımlı
görüntü de tam görüntü kadar iş yapar, çünkü birleştirmenin ürettiği bölüt **yeni bir
dosyadır**: içeriğinin tamamı zaten depoda olsa bile, girdileri değil kendisi kopyalanır. On
altıncı gün bunun uç hâlidir — iki birleştirme dizini tek bölüte indirir ve artımlı görüntü
1.253.638 baytın hepsini yeniden yazar. Artımlılık, bölütlerin değişmezliğinden gelen bir
kazançtır ve birleştirme tam da o değişmezliği kullanıp yeni dosya ürettiği için düzenli
aralıklarla sıfırlanır.

Son sütun üçüncü bir sonucu verir. Depoda tutulan 3.180.562 bayttır, oysa canlı dizin
1.253.638 bayttır. Depo, canlı dizinin iki buçuk katını tutar; fazlalık, birleştirmeyle
geçersizleşen ama eski görüntüler onlara başvurduğu için silinemeyen bölüt dosyalarıdır. Eski
görüntüler düşürülmeden bu alan geri gelmez. Birleştirme çarpanını düşürmek — bir önceki
derste sorgu tarafında küçük bir kazançtı — burada hem artımlı görüntü trafiğini hem depo
boyutunu doğrudan büyütür.

## Geri Yükleme mi, Yeniden Dizinleme mi

Dizin kaybolduğunda iki yol vardır. Depodaki son görüntünün dosyaları yerine taşınabilir, ya da
katalog kaynağındaki 8.000 kayıt yeniden dizinlenebilir. İkincisi ilk bakışta yedeğe hiç
gerek bırakmaz. Ölçüm iki yolun neyi ödediğini ve **ne getirdiğini** ayırır: üçüncü satırda
yeniden dizinleme, o sırada çözümleyici zinciri değiştirilmiş bir sistemde koşar.

```js
// kurtarma.mjs — geri yükleme ile yeniden dizinlemenin karşılaştırması
import { mkdirSync, readFileSync, writeFileSync, statSync } from 'node:fs';
import { derlemUret, yigin, goruntuAl, ara, metin, temel, gelismis } from './yedek.mjs';

const derlem = derlemUret(8000, 20260731);
const SORGU = [['çocuk', 'edebiyatı', 'öykü'], ['yitik', 'kapılar'],
  ['kütüphaneler', 'bellek'], ['denizde', 'ada'], ['polisiye', 'kent']];

function kur(coz) {                           // aynı günlük partiler, aynı birleştirme politikası
  const y = yigin(4);
  let belirtec = 0;
  for (let g = 0; g < 16; g++) {
    const parti = derlem.slice(g * 500, (g + 1) * 500);
    for (const b of parti) belirtec += coz(metin(b)).length;
    y.ekle(parti, coz);
  }
  return { bolutler: y.bolutler, belirtec };
}

const asil = kur(temel);                      // özgün dizin ve son görüntünün içeriği
const gor = goruntuAl(asil.bolutler, 'depo', true);

mkdirSync('dizin', { recursive: true });      // geri yükleme: depodaki dosyalar yerine taşınır
let geriBayt = 0;
for (const ad of gor.liste) {
  writeFileSync(`dizin/${ad}`, readFileSync(`depo/${ad}`));
  geriBayt += statSync(`dizin/${ad}`).size;
}

const olc = (bolutler, coz) => {
  let bayt = 0, sozluk = 0, eslesen = 0;
  const ilk = [];
  for (const b of bolutler) { bayt += b.bayt; sozluk += b.sozluk.size; }
  for (const s of SORGU) {
    const c = ara(bolutler, coz(s.join(' ')));
    eslesen += c.eslesen; ilk.push(c.ilkK);
  }
  return { bayt, sozluk, eslesen, ilk };
};
const temelOlcu = olc(asil.bolutler, temel);
const fark = (o) => {                         // özgün dizine göre ilk on değişimi
  let cikan = 0, oynayan = 0;
  for (let q = 0; q < SORGU.length; q++) {
    for (const id of temelOlcu.ilk[q]) if (!o.ilk[q].includes(id)) cikan++;
    for (let i = 0; i < 10; i++) if (o.ilk[q][i] !== temelOlcu.ilk[q][i]) oynayan++;
  }
  return [cikan, oynayan];
};

const yeni = kur(gelismis);
const yeniOlcu = olc(yeni.bolutler, gelismis);
console.log('derlem: 8000 belge, tohum 20260731 | 5 sorgu, ilk on: 50 basamak');
console.log('yol                              kopyalanan  işlenen belge  belirteç  dizin bayt  sözlük  eşleşen  çıkan  oynayan');
const satir = (ad, kop, belge, belirtec, o) => console.log(ad.padEnd(32),
  String(kop).padStart(10), String(belge).padStart(14), String(belirtec).padStart(9),
  String(o.bayt).padStart(11), String(o.sozluk).padStart(7), String(o.eslesen).padStart(8),
  String(fark(o)[0]).padStart(6), String(fark(o)[1]).padStart(8));
satir('geri yükleme', geriBayt, 0, 0, temelOlcu);
satir('yeniden dizinleme (aynı zincir)', 0, 8000, asil.belirtec, temelOlcu);
satir('yeniden dizinleme (yeni zincir)', 0, 8000, yeni.belirtec, yeniOlcu);
```

```
derlem: 8000 belge, tohum 20260731 | 5 sorgu, ilk on: 50 basamak
yol                              kopyalanan  işlenen belge  belirteç  dizin bayt  sözlük  eşleşen  çıkan  oynayan
geri yükleme                        1253638              0         0     1253638     363     7879      0        0
yeniden dizinleme (aynı zincir)           0           8000    153690     1253638     363     7879      0        0
yeniden dizinleme (yeni zincir)           0           8000    121690      919902      79    17387     41       49
```

İlk iki satır aynı dizini üretir: 1.253.638 bayt, 363 terim, beş sorguda 7.879 eşleşen belge ve
ilk onda tek basamak farkı yok. Aynı sonuca giden iki yolun ödediği ise bambaşkadır. Geri
yükleme 1.253.638 bayt taşır ve hiçbir belgeye dokunmaz; yeniden dizinleme tek bayt taşımaz ama
8.000 belgeyi okuyup **153.690 belirteç** üretir. Süre koşum ortamına bağlıdır ve burada
basılmaz; karar bu iki niceliğin nasıl ölçekleneceğine bakılarak verilir. Geri yüklemenin
bedeli dizin boyutuyla, yeniden dizinlemenin bedeli kaynak belge sayısı ve belge başına
belirteçle büyür. Yeniden dizinlemenin ayrıca sessiz bir koşulu vardır: kaynak kayıtların
eksiksiz durması. Dizin, katalogda artık bulunmayan bir alanı da tutuyorsa yeniden dizinleme
onu geri getiremez.

Üçüncü satır, yeniden dizinlemenin neden yedeğin yerine geçmediğini gösterir. Çözümleyici
zinciri durak sözcük atma ve kök bulma ile genişletildiğinde aynı 8.000 kayıt farklı bir dizin
üretir: 153.690 yerine 121.690 belirteç (aradaki 32.000, atılan dolgu sözcükleridir), 363 yerine
79 terim, 1.253.638 yerine 919.902 bayt. Etki yanıtta görünür. Beş sorgunun eşleşen belge
toplamı 7.879'dan **17.387'ye** çıkar, çünkü "kapılar" artık "kapı" ile aynı terime iner ve
çekimli biçimler tek gönderi listesinde toplanır — anma yükselir. Sıra da yeniden kurulur: ilk
on sonucun elli basamağının 49'u değişir ve 41 belge ilk ondan bütünüyle düşer. Bu bir arıza
değildir, kararın kendisidir; ama geri yükleme ile aynı işlem sayılamaz. Geri yükleme dizini
**olduğu gibi** getirir, yeniden dizinleme o günkü yapılandırmayla **yeniden üretir**.

## Özet

- Bölütler değişmez olduğu için görüntü artımlı alınabilir: birleştirme olmayan günlerde
  kopyalanan bayt o günün tek bölütüdür (yaklaşık 81.500), tam görüntü ise dizinin tamamıdır.
- On altı günün toplamında tam görüntüler 10.790.530 bayt, artımlı görüntüler 3.180.562 bayt
  kopyaladı.
- Birleştirme artımlılığı bozar: birleştirmenin çalıştığı günde artımlı görüntü tam görüntü
  kadar iş yapar, çünkü birleşen bölüt yeni bir dosyadır; on altıncı günde 1.253.638 baytın
  hepsi yeniden kopyalandı.
- Depo 3.180.562 bayt tutar, canlı dizin 1.253.638 bayt: fark, eski görüntülerin başvurduğu
  için silinemeyen geçersiz bölüt dosyalarıdır.
- Geri yükleme 1.253.638 bayt taşıyıp sıfır belge işler, yeniden dizinleme sıfır bayt taşıyıp
  8.000 belge ve 153.690 belirteç işler; ikisi aynı dizini verir.
- Çözümleyici zinciri değişmişse yeniden dizinleme aynı dizini vermez: eşleşen belge 7.879'dan
  17.387'ye çıktı, ilk on sonucun 49 basamağı değişti ve 41 belge ilk ondan düştü.

## Sonraki Adım

Bu ders bir dizinin bütün olarak kopyalanmasını, taşınmasını ve yeniden üretilmesini ele aldı.
Hepsinin ortak varsayımı, kümeye erişen herkesin bütün dizini görmeye yetkili olduğuydu:
görüntü alan da, geri yükleyen de, sorgulayan da aynı belgeleri görüyordu. Kütüphane
katalogunda bu doğru değildir — kişisel ödünç kayıtları, satın alma notları ve bağış
yazışmaları aynı dizinde durabilir ama her kullanıcıya açık değildir. Sonraki ders bu ayrımı
ölçer: aynı sorgu iki farklı rolde koştuğunda dönen kümenin nasıl daraldığı, belge ve alan
düzeyinde süzmenin sıraya ne yaptığı ve bu süzmenin sorgu maliyetine ne eklediği.
