All pastes #29805 Raw Edit

neuron

public c v1 · immutable
#29805 ·published 2005-11-20 23:44 UTC
rendered paste body
/* direct_compress for fusecompress. * Copyright (C) 2005 Anders Aagaard <aagaande@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ /*  implement open/close/read/write that I put in compress_module    - change functions using compress/decompress there to use a function that uses the open/close/read/write functions instead?  add direct_open/direct_close/direct_read/direct_write to fusecompress'es functions.    - also fi->fh has to become filedata_h, and on the top of every function using it we need to LOCK_ENTRY and UNLOCK_ENTRY on the bottom.    - fuse's open/release/write/read/truncate atleast (trunc has to count as write, and decompress file if we have more accesses)    - truncate is special, we can set file to RAW without running it through decompress first.*/ #include <pthread.h>#include <assert.h>#include <string.h>#include <stdlib.h>#include <unistd.h> #include "list.h"#include "direct_compress.h"pthread_mutex_t database_lock;database_entry_h database;static unsigned int gethash (const char *ptr){	unsigned int hash;	/* todo, tweak this, no more len, base it on ptr[0]? */ 	for (hash = 0; *ptr; ptr++)		hash = 31 * hash + *ptr;	return hash;}// Returns locked database entry.database_entry_h *direct_open(char *filename, struct compress_module *compressor){	assert(filename);	database_entry_h *entry = NULL;	unsigned int target_hash = gethash(filename);		LOCK_DATABASE;	_CACHE_MSG("direct_open %s\n",filename);	list_for_each_entry(entry, &database.list,list) {		LOCK_ENTRY;		if (entry->filename_hash == target_hash && (strcmp(entry->filename,filename) == 0)) {			UNLOCK_DATABASE;			entry->compressor = compressor;			entry->accesses++;			return entry; // RETURNED WITH LOCK		}	}		// No entry found, allocate new.	entry = malloc(sizeof(database_entry_h));	LOCK_ENTRY;	entry->compressor = compressor;	entry->accesses = 1;	entry->filename = strdup(filename);	entry->filename_hash = target_hash;	list_add(&entry->list,&database.list);		UNLOCK_DATABASE;}// We need LOCK_ENTRY here.void direct_close(filedata_h *filedata){	if (filedata->compressor_data) {		filedata->database->compressor->close((void *)filedata->compressor_data);		free(filedata->compressor_data);		filedata->compressor_data = NULL;	}}/*  We need LOCK_ENTRY here.  This function returns TRUE on data read ok (length in returned_len), FALSE on use pread instead and FAIL on error.*/int direct_decompress(filedata_h *filedata,void *buffer, size_t size, int offset, int *returned_len){	// If offset is wrong, we need to close and open in raw mode.	if (offset != filedata->offset) {		direct_close(filedata);		if (decompress(filedata->fd,filedata->database->filename,filedata->database->compressor) == FAIL)			return FAIL;		filedata->database->compressor = NULL;		return FALSE;	}	// Open file if neccesary	assert(filedata->database->compressor);	if (!filedata->compressor_data) {		assert(filedata->offset == 0);		filedata->compressor_data = COMPRESSOR_OPEN(filedata->fd,"rb");		if (!filedata->compressor_data)			return FAIL;	}		// Do actual decompressing.	assert(filedata->compressor_data);	*returned_len = COMPRESSOR_READ(filedata->compressor_data,buffer,size);	if (*returned_len == -1)		return FAIL;	return TRUE;}/*  We need LOCK_ENTRY here.  This function returns TRUE on data read ok (length in returned_len), FALSE on use pwrite instead and FAIL on error.*/int direct_compress(filedata_h *filedata, void *buffer, size_t size, int offset, int *returned_len){	// If accesses > 0 we need to decompress, can't have write and read (... actually we can, but lets ignore that for now) or multiple writes	if (offset != filedata->offset || filedata->database->accesses > 0) {		direct_close(filedata);		if (decompress(filedata->fd,filedata->database->filename,filedata->database->compressor) == FAIL)			return FAIL;		filedata->database->compressor = NULL;		return FALSE;	}		// Open file if neccesary	assert(filedata->database->compressor);	if (!filedata->compressor_data) {		assert(filedata->offset == 0);		filedata->compressor_data = COMPRESSOR_OPEN(filedata->fd,"wb9");		if (!filedata->compressor_data)			return FAIL;	}		// Do actual compressing.	assert(filedata->compressor_data);	*returned_len = COMPRESSOR_WRITE(filedata->compressor_data,buffer,size);	if (*returned_len == -1)		return FAIL;	return TRUE;}