File:  [parser3project] / parser3 / src / main / pa_code_cache.C
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Mon Oct 5 17:50:18 2026 UTC (2 weeks, 6 days ago) by moko
Branches: MAIN
CVS tags: HEAD
code caching implemented for httpd mode: it records and then replays the compilation using the cached methods (implements feature #1302), pa_code_cache.h/.C added

/** @file
	Parser: compiled code cache.

	Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
	Authors: Konstantin Morshnev <moko@design.ru>
*/

#include "pa_code_cache.h"

volatile const char * IDENT_PA_CODE_CACHE_C="$Id: pa_code_cache.C,v 1.1 2026/10/05 17:50:18 moko Exp $" IDENT_PA_CODE_CACHE_H;

#ifdef CODE_CACHE

Code_cache::Code_cache(const String& afile_spec): file_spec(afile_spec), file_no(0), fsize(0), fmtime(0) {
	time_t atime, ctime;
	file_stat(file_spec, fsize, atime, fmtime, ctime, false);
}

void Code_cache::add(Kind kind, const String* name, Method* method) {
	Action action={kind, name, method, Operation::Origin::create(0, 0, 0)};
	actions+=action;
}

void Code_cache::add_use(const String* name, Operation::Origin origin) {
	Action action={USE, name, 0, origin};
	actions+=action;
}

bool Code_cache::unchanged() {
	uint64_t size;
	time_t atime, mtime, ctime;
	return file_stat(file_spec, size, atime, mtime, ctime, false) && size==fsize && mtime==fmtime;
}

// filled while the httpd config runs, only read in the subsequent requests
static HashString<Code_cache*>* code_cache=0;
// file_list of the config run
static Array<String::Body>* code_cache_files=0;

static bool code_cache_recording=false;
static bool code_cache_enabled=true;

void Code_cache_manager::start() {
	code_cache=new HashString<Code_cache*>;
	code_cache_recording=true;
}

void Code_cache_manager::finish(Request& r) {
	code_cache_recording=false;
	if(code_cache_enabled) {
		code_cache_files=new Array<String::Body>;
		code_cache_files->append(r.file_list);
	} else
		code_cache=0;
}

void Code_cache_manager::set_enabled(bool aenabled) {
	if(code_cache_recording)
		code_cache_enabled=aenabled;
}

void Code_cache_manager::add_files(Array<String::Body>& file_list) {
	if(code_cache_files) // the request has only the pseudo files yet, the same as in the config run
		file_list.append(*code_cache_files, file_list.count());
}

Code_cache* Code_cache_manager::get(const String& file_spec) {
	if(code_cache && !code_cache_recording)
		if(Code_cache* code=code_cache->get(file_spec))
			if(code->unchanged())
				return code;
	return 0;
}

Code_cache* Code_cache_manager::create(const String& file_spec) {
	// size and time are taken before reading
	return code_cache_recording ? new Code_cache(file_spec) : 0;
}

void Code_cache_manager::put(Code_cache& code) {
	code_cache->put(code.file_spec, &code);
}

#endif

E-mail: