<commit_before><?
/**
 * MT-safe file database baseclass.
 * 
 * Transaction-based operations which guarantees atomicity. Subclasses should
 * implement txReadData and/or txWriteData to make any sense.
 */
class FileDB {
	public $file;
	public $createmode;
	public $data = null;
	
	function __construct($file, $createmode=0660) {
		$this->file = $file;
		$this->createmode = $createmode;
	}
	
	protected $txExclusive = true;
	protected $txFp = false;
	
	function begin($exclusive=true) {
		if ($this->txFp !== false)
			throw new LogicException('a transaction is already active');
		$this->txExclusive = $exclusive;
		$this->txFp = @fopen($this->file, 'r+');
		if (file_exists($this->file) && !is_writable($this->file))
			throw new RuntimeException($this->file.' is not writable');
		if ( ($this->txFp === false) && (($this->txFp = fopen($this->file, 'x+')) !== false) ) {
			if ($this->createmode !== false)
				chmod($this->file, $this->createmode);
		}
		if ($this->txFp === false)
			throw new RuntimeException('fopen('.var_export($this->file,1).', "x+") failed');
		if ($this->txExclusive && !flock($this->txFp, LOCK_EX)) {
			fclose($this->txFp);
			throw new RuntimeException('flock(<txFp>, LOCK_EX) failed');
		}
	}
	
	protected function txReadData() {
		if ($this->txFp === false)
			throw new LogicException('transaction is not active');<commit_msg>support for "skeleton file" in FileDB<commit_after><?
/**
 * MT-safe file database baseclass.
 * 
 * Transaction-based operations which guarantees atomicity. Subclasses should
 * implement txReadData and/or txWriteData to make any sense.
 */
class FileDB {
	public $file;
	public $skeleton_file;
	public $createmode;
	public $data = null;
	
	function __construct($file, $skeleton_file=null, $createmode=0660) {
		$this->file = $file;
		$this->skeleton_file = $skeleton_file;
		$this->createmode = $createmode;
	}
	
	protected $txExclusive = true;
	protected $txFp = false;
	
	function begin($exclusive=true) {
		if ($this->txFp !== false)
			throw new LogicException('a transaction is already active');
		$this->txExclusive = $exclusive;
		$this->txFp = @fopen($this->file, 'r+');
		if (file_exists($this->file) && !is_writable($this->file))
			throw new RuntimeException($this->file.' is not writable');
		if ($this->skeleton_file) {
			copy($this->skeleton_file, $this->file);
			if ($this->createmode !== false)
				chmod($this->file, $this->createmode);
			$this->txFp = fopen($this->file, 'r+');
		}
		elseif ( ($this->txFp === false) && (($this->txFp = fopen($this->file, 'x+')) !== false) ) {
			if ($this->createmode !== false)
				chmod($this->file, $this->createmode);
		}
		if ($this->txFp === false)
			throw new RuntimeException('fopen('.var_export($this->file,1).', "x+") failed');
		if ($this->txExclusive && !flock($this->txFp, LOCK_EX)) {
			fclose($this->txFp);
			throw new RuntimeException('flock(<txFp>, LOCK_EX) failed');
		}
	}
	
	protected function txReadData() {
		if ($this->txFp === false)
			throw new LogicException('transaction is not active');
{'fraction_non_alphanumeric': 0.18325642715886617, 'fraction_numerical': 0.0032959789057350032, 'mean_word_length': 4.468468468468468, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6386169', 'n_tokens_mistral': 1142, 'n_tokens_neox': 1044, 'n_words': 241}