回精華區
作者itoc, 信區: itoc
標題[文件] rec_*() 的意思
時間04/02/07
作者: itoc (Internet Explorer) 看板: plan
標題: [文件] rec_*() 的意思
時間: Fri Mar 14 10:24:22 2003

  fpath:   索引的路徑 (file path)
  data:    資料
  size:    資料的大小 (單位: bytes)
  fchk:    複查的函式 (check function)
  fref:    更新的函式 (refresh function)
  fsync:   同步的函式 (synchronize function)
  pos:     第幾筆位置 (position)
  num:     數量 (number)

: rec_add.c  (Record Add)

  [語法] rec_add(fpath, data, size)
  [說明] 把 data 這筆資料,附加在 fpath 最後

  [範例] pal_add()

    PAL pal;

    /* 製造一個 PAL */
    memset(&pal, 0, sizeof(PAL));
    vget(b_lines, 0, "友誼:", pal.ship, sizeof(pal.ship), DOECHO);
    pal.ftype = vans("壞人(Y/N)?[N] ") == 'y' ? PAL_BAD : 0;
    strcpy(pal.userid, acct.userid);
    pal.userno = userno;

    /* 將 PAL 寫入 */
    rec_add(xo->dir, &pal, sizeof(PAL));


: rec_bot.c  (Record Bottom)

  [語法] rec_bot(fpath, data, size)
  [說明] 把 data 這筆資料,附加在 fpath 第一筆置底文的前面

  [範例] do_unanonymous()

    HDR hdr;

    /* 製造一個 HDR */
    hdr_stamp(folder, HDR_LINK | 'A', &hdr, fpath);
    strcpy(hdr.owner, cuser.userid);
    strcpy(hdr.title, ve_title);

    /* 將 HDR 寫入 */
    rec_bot(folder, &hdr, sizeof(HDR));


: rec_del.c  (Record Delete)

  [語法] rec_del(fpath, size, pos, fchk)
  [說明] 把 fpath 的第 pos 筆資料刪除
         為避免刪錯資料,刪除前要做 fchk 確認

  [範例] pal_delete()

    /* 無條件將游標所在這筆資料刪除 */
    rec_del(xo->dir, sizeof(PAL), xo->pos, NULL);

  [範例] post_delete()

    static int currchrono;

    int
    cmpchrono(hdr)
      HDR *hdr;
    {
      return hdr->chrono == currchrono;
    }

    static int
    post_delete(xo)
      XO *xo;
    {
      /* 將游標所在這筆資料刪除,但刪除前要做 chrono 的 compare
         若相同才刪除,以免誤砍 */
      currchrono = hdr->chrono;
      rec_del(xo->dir, sizeof(HDR), xo->pos, cmpchrono);
    }


: rec_get.c  (Record Get)

  [語法] rec_get(fpath, data, size, pos)
  [說明] 把 fpath 的第 pos 筆資料取出放到 data

  [範例] pal_loadpal()

    PAL pal;

    /* 從好友名單中取中第 i 筆資料 */
    if (rec_get(fpath, &pal, sizeof(PAL), i) >= 0)
    {
      /* 如果這筆資料不是壞人,就加入板友名單 */
      if (!(pal.ftype & PAL_BAD))
        rec_add(dir, &pal, sizeof(PAL));
    }


: rec_ins.c  (Record Insert)

  [語法] rec_ins(fpath, data, size, pos, num)
  [說明] 把 data 這 num 筆資料,插入在 fpath 的第 pos 筆位置

  [範例] gem_add()

    HDR ghdr;

    /* 製造一個 HDR */
    ...
    ...

    /* 詢問要插入的位置 */
    ans = vans("存放位置 A)加到最後 I/N)插入目前位置 Q)離開 [A] ");

    if (ans == 'i')         /* 若選 Insert 則插入目前位置 */
      rec_ins(xo->dir, &ghdr, sizeof(HDR), xo->pos, 1);
    else if (ans == 'n')    /* 若選 Next 則插入下一筆位置 */
      rec_ins(xo->dir, &ghdr, sizeof(HDR), xo->pos + 1, 1);
    else                    /* 反之,則附加在最後 */
      rec_add(xo->dir, &ghdr, sizeof(HDR));


: rec_num.c  (Record Number)

  [語法] rec_num(fpath, size)
  [說明] 回傳 fpath 總共有幾筆資料

  [範例] acct_show()

    usr_fpath(buf, uid, fn_dir);
    prints("  個人信件:%d 封", rec_num(buf, sizeof(HDR)));


: rec_put.c  (Record Put/Update)

  [語法] rec_put(fpath, data, size, pos, fchk)
  [說明] 以 data 去更新 fpath 的第 pos 筆資料
         為避免更新錯資料,更新前要做 fchk 確認

  [範例] pal_change()

    PAL *pal;

    /* 重新編輯游標所在這筆好友友誼 */
    pal = (PAL *) xo_pool + cur;
    vget(b_lines, 0, "友誼:", pal->ship, sizeof(pal->ship), GCARRY);
    pal->ftype = vans("壞人(Y/N)?[N] ") == 'y' ? PAL_BAD : 0;

    /* 無條件更新這筆資料 */
    rec_put(xo->dir, pal, sizeof(PAL), pos, NULL);

  [範例] post_mark()

    HDR *hdr;

    /* 加上/去除 mark */
    hdr = (HDR *) xo_pool + xo->pos - xo->top;
    hdr->xmode ^= POST_MARKED;

    /* 將游標所在這筆資料更新,但更新前要做 chrono 的 compare
       若相同才更新,以免更新錯篇 */
    currchrono = hdr->chrono;
    rec_put(xo->dir, hdr, sizeof(HDR), xo->pos, cmpchrono);


: rec_ref.c  (Record Refresh/Update)

  [語法] rec_ref(fpath, data, size, pos, fchk, fref)
  [說明] 以 data 去更新 fpath 的第 pos 筆資料
         為避免更新錯資料,更新前要做 fchk 確認
         更新時做的動作是 fref
  [備註] 這是一個類似 rec_put() 的函式,差別在於多了個 fref
         可以拿硬碟中的索引檔直接來改,避免 XO 和 .DIR 不同步的問題

  [範例] post_score()

    static int curraddscore;

    static void
    addscore(hdd, ram)
      HDR *hdd, *ram;
    {
      /* 直接把 .DIR 中的 score 更新,不管 XO 裡面的 score 是記錄多少 */
      hdd->score += curraddscore;
    }

    static int
    post_score(xo)
      XO *xo;
    {
      HDR *hdr;
      ...
      ans = vans("加減分 1)推文 2)唾棄 Q)取消?[Q] ");
      if (ans == '1')       /* 加分 */
        curraddscore = 1;
      else if (ans == '2')  /* 扣分 */
        curraddscore = -1;

      currchrono = hdr->chrono;
      rec_ref(dir, hdr, sizeof(HDR), pos, cmpchrono, addscore);
      ...
    }


: rec_sync.c (Record Synchronize)

  [語法] rec_sync(fpath, size, fsync, fchk)
  [說明] 把 fpath 這個索引檔同步並排序

  [範例] pal_sync()

    static int
    cmppal(a, b)
      PAL *a, *b;
    {
      /* 依 userid 排序 */
      return str_cmp(a->userid, b->userid);
    }

    static int
    chkpal(pal)
      PAL *pal;
    {
      /* 檢查好友名單中每筆資料,若 userno 錯誤,刪除該筆資料 */
      int userno = pal->userno;
      return (userno > 0 && userno == acct_userno(pal->userid));
    }

    void
    pal_sync()
    {
      /* 檢查好友名單中每筆資料是否 userno 正確,並依 userid 排序 */
      usr_fpath(fpath, cuser.userid, fn_pal);
      rec_sync(fpath, sizeof(PAL), cmppal, chkpal);
    }


: rec_mov.c  (Record Move)

  rec_mov.c 目前都沒用到


> ---------------------------------------------------------- <

  至於要用 HDR hdr; PAL pal; ...
  還是用 HDR *hdr; PAL *pal; ... 指標


: 如果要新增/附加一筆資料,就是用 HDR hdr;

  HDR hdr;

  /* 製造一個 HDR */
  hdr.chrono = time(0);
  strcpy(hdr.owner, cuser.userid);

  /* 寫回硬碟 */
  rec_add(folder, &hdr, sizeof(HDR));


: 如果要更新一筆資料,就是用 HDR *hdr;

  HDR *hdr;

  /* 從 XO 中取出目前游標所在這筆資料的值 */
  hdr = (HDR *) xo_pool + xo->pos - xo->top;

  /* 更新這筆資料 */
  hdr->xmode ^= POST_MARKED;

  /* 寫回硬碟 */
  currchrono = hdr->chrono;
  rec_put(xo->dir, hdr, sizeof(HDR), xo->pos, cmpchrono);

--
□ 本文章由 itocitoc.Dorm-GD2.NCTU.edu.tw 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻