📄 cache.c
字号:
/* $Id: cache.c,v 3.0 1992/02/01 03:09:32 davison Trn $ *//* This software is Copyright 1991 by Stan Barber. * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made. * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk. */#include "EXTERN.h"#include "common.h"#include "INTERN.h"#include "cache.h"#include "EXTERN.h"#include "intrp.h"#include "search.h"#include "ng.h"#include "trn.h"#include "ngdata.h"#include "term.h"#include "final.h"#include "artsrch.h"#include "head.h"#include "bits.h"#include "rcstuff.h"#include "hash.h"#include "rthread.h"#include "rt-ov.h"#include "rt-select.h"#include "rt-util.h"#include "util.h"#ifdef PENDING# ifdef ARTSEARCH COMPEX srchcompex; /* compiled regex for searchahead */# endif#endifHASHTABLE *subj_hash = 0;int subject_cmp _((char *,int,HASHDATUM));voidcache_init(){ ;}NG_NUM cached_ng = -1;time_t cached_time = 0;ART_NUM cached_cnt = 0;ART_NUM cached_absfirst = 0;voidbuild_cache(){ if (cached_ng == ng && cached_absfirst == absfirst && time((time_t*)NULL) < cached_time + 6*60*60L) { grow_cache(lastart); rc_to_bits(); thread_grow(); return; } close_cache(); cached_ng = ng; cached_absfirst = absfirst; cached_time = time((time_t*)NULL); cached_cnt = lastart-absfirst+2 + 5; article_list = (ARTICLE*) safemalloc((MEM_SIZE)(cached_cnt * sizeof (ARTICLE))); bzero((char*)article_list, cached_cnt * sizeof (ARTICLE)); subj_hash = hashcreate(201, subject_cmp); /*TODO: pick a better size */ rc_to_bits(); /* sets firstart */ first_cached = thread_always? absfirst : firstart; last_cached = first_cached-1; cached_all_in_range = FALSE;#ifdef PENDING subj_to_get = xref_to_get = firstart;#endif#ifndef USE_NNTP setmissingbits();#endif /* Cache as much data in advance as possible, possibly threading ** articles as we go. */ thread_open();}#define FIXPTR(p) (!(p) || (p)<old_list || ((p)-old_list) > (lastart-absfirst)\ ? (p) : (article_list + ((p)-old_list)))voidgrow_cache(newlast)ART_NUM newlast;{ ART_NUM new_cnt = newlast-absfirst+2; if (new_cnt > cached_cnt) { ARTICLE *old_list = article_list; new_cnt += 5; article_list = (ARTICLE*)saferealloc((char*)article_list, (MEM_SIZE)(new_cnt * sizeof (ARTICLE))); bzero((char*)(article_list+cached_cnt), (new_cnt-cached_cnt) * sizeof (ARTICLE)); if (article_list != old_list) { register ARTICLE *ap; register SUBJECT *sp; for (sp = first_subject; sp; sp = sp->next) { sp->thread = FIXPTR(sp->thread); sp->articles = FIXPTR(sp->articles); if (sp->thread) { for (ap = sp->thread; ap; ap = bump_art(ap)) { ap->child1 = FIXPTR(ap->child1); ap->parent = FIXPTR(ap->parent); ap->sibling = FIXPTR(ap->sibling); ap->subj_next = FIXPTR(ap->subj_next); } } else { for (ap = sp->articles; ap; ) ap = ap->subj_next = FIXPTR(ap->subj_next); } } artp = FIXPTR(artp); curr_artp = FIXPTR(curr_artp); recent_artp = FIXPTR(recent_artp); } cached_cnt = new_cnt; } cached_time = time((time_t*)NULL);}voidclose_cache(){ SUBJECT *sp, *next; ARTICLE *ap; ART_NUM i; if (subj_hash) { hashdestroy(subj_hash); subj_hash = 0; } /* Free all the subjects. */ for (sp = first_subject; sp; sp = next) { next = sp->next; free(sp->str); free((char*)sp); } first_subject = last_subject = Nullsubj; subject_count = 0; /* just to be sure */ parsed_art = 0; if (artptr_list) { free((char*)artptr_list); artptr_list = Null(ARTICLE**); } artptr = Null(ARTICLE**); thread_close(); if (cached_cnt) { for (i = 0, ap = article_list; i < cached_cnt; i++, ap++) clear_article(ap); free((char*)article_list); cached_cnt = 0; } cached_ng = -1;}/* The article has all it's data in place, so add it to the list of articles** with the same subject.*/voidcache_article(ap)register ARTICLE *ap;{ register ARTICLE *next, *ap2; if (!(next = ap->subj->articles) || ap->date < next->date) ap->subj->articles = ap; else { while ((next = (ap2 = next)->subj_next) && next->date <= ap->date) ; ap2->subj_next = ap; } ap->subj_next = next; ap->flags |= AF_CACHED; if (!(ap->flags & AF_READ) ^ sel_rereading) { if (selected_only) { if (ap->subj->flags & sel_mask) { ap->flags |= sel_mask; selected_count++; } } else if (ap->subj->flags & SF_WASSELECTED) select_article(ap, 0); else { ap->subj->flags |= SF_VISIT; if (sel_mode == SM_THREAD) ap->subj->thread->subj->flags |= SF_VISIT; } }}voidcheck_poster(ap)register ARTICLE *ap;{ if (auto_select_postings && !(ap->flags & AF_MISSING)) { if (ap->flags & AF_FROMTRUNCED) { strcpy(cmd_buf,realname); if (strEQ(ap->from,compress_name(cmd_buf,16))) { untrim_cache = TRUE; fetchfrom(article_num(ap),FALSE); untrim_cache = FALSE; } } if (!(ap->flags & AF_FROMTRUNCED)) { if (instr(ap->from,phostname,FALSE)) { if (instr(ap->from,logname,TRUE)) select_subthread(ap,AF_AUTOSELECT); else {#ifdef SLOW_BUT_COMPLETE_POSTER_CHECKING char *reply_buf = fetchlines(article_num(ap),REPLY_LINE); if (instr(reply_buf,logname,TRUE)) select_subthread(ap,AF_AUTOSELECT); free(reply_buf);#endif } } } }}/* The article turned out to be a duplicate, so remove it from the cached** list and possibly destroy the subject (should only happen if the data** was corrupt and the duplicate id got a different subject).*/voiduncache_article(ap, remove_empties)register ARTICLE *ap;bool_int remove_empties;{ register ARTICLE *next, *ap2; if (ap->subj) { if ((ap->flags & (AF_CACHED|AF_MISSING)) == AF_CACHED) { if ((next = ap->subj->articles) == ap) ap->subj->articles = ap->subj_next; else if (next) { while (next && (next = (ap2 = next)->subj_next) != ap) ; ap2->subj_next = next; } } if (remove_empties && !ap->subj->articles) { register SUBJECT *sp = ap->subj; if (sp == first_subject) first_subject = sp->next; else sp->prev->next = sp->next; if (sp == last_subject) last_subject = sp->prev; else sp->next->prev = sp->prev; free((char*)sp); ap->subj = Nullsubj; subject_count--; } } onemissing(ap);}/* get the header line from an article's cache or parse the article trying */char *fetchcache(artnum,which_line)ART_NUM artnum;int which_line;{ register char *s; register ARTICLE *ap; register bool cached = (htype[which_line].ht_flags & HT_CACHED); /* find_article() returns a Nullart if the artnum value is invalid */ if (!(ap = find_article(artnum)) || (ap->flags & AF_MISSING)) return nullstr; if (cached && (s=get_cached_line(ap,which_line,untrim_cache)) != Nullch) return s; if (!parseheader(artnum)) return nullstr; if (cached && (s=get_cached_line(ap,which_line,untrim_cache)) != Nullch) return s; return Nullch;}/* Return a pointer to a cached header line for the indicated article.** Truncated headers (e.g. from a .thread file) are optionally ignored.*/char *get_cached_line(ap, which_line, no_truncs)register ARTICLE *ap;int which_line;bool_int no_truncs;{ register char *s; switch (which_line) { case SUBJ_LINE: if (!ap->subj || (no_truncs && (ap->subj->flags & SF_SUBJTRUNCED))) s = Nullch; else s = ap->subj->str + ((ap->flags & AF_HAS_RE) ? 0 : 4); break; case FROM_LINE: if (no_truncs && (ap->flags & AF_FROMTRUNCED)) s = Nullch; else s = ap->from; break;#ifdef DBM_XREFS case NGS_LINE:#else case XREF_LINE:#endif s = ap->xrefs; break; case MESSID_LINE: s = ap->msgid; break; default: s = Nullch; break; } return s;}voidset_subj_line(ap, s, size)register ARTICLE *ap;register char *s; /* not yet allocated, so we can tweak it first */register int size;{ HASHDATUM data; SUBJECT *sp; char *s2, *subj_start = get_subject_start(s); if (s != subj_start) { size -= subj_start - s; ap->flags |= AF_HAS_RE; } if (ap->subj && strnEQ(ap->subj->str+4, subj_start, size)) return; s2 = safemalloc(size + 4 + 1); strcpy(s2, "Re:"); safecat(s2, subj_start, size+5); if (ap->subj) { /* This only happens when we freshen truncated subjects */ hashdelete(subj_hash, ap->subj->str+4, strlen(ap->subj->str+4)); free(ap->subj->str); ap->subj->str = s2; data.dat_ptr = (char*)ap->subj; hashstore(subj_hash, s2 + 4, size, data); } else { data = hashfetch(subj_hash, s2 + 4, size); if (!(sp = (SUBJECT*)data.dat_ptr)) { sp = (SUBJECT*)safemalloc(sizeof (SUBJECT)); bzero((char*)sp, sizeof (SUBJECT)); subject_count++; if ((sp->prev = last_subject) != NULL) sp->prev->next = sp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -