353 lines
9.4 KiB
C++
353 lines
9.4 KiB
C++
// -*- C++ -*-
|
|
|
|
//=============================================================================
|
|
/**
|
|
* @file Filecache.h
|
|
*
|
|
* @author James Hu
|
|
*/
|
|
//=============================================================================
|
|
|
|
|
|
#ifndef ACE_FILECACHE_H
|
|
#define ACE_FILECACHE_H
|
|
|
|
#include /**/ "ace/pre.h"
|
|
|
|
#include "ace/Mem_Map.h"
|
|
|
|
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
|
|
|
#include "ace/Hash_Map_Manager_T.h"
|
|
#include "ace/Null_Mutex.h"
|
|
#include "ace/Synch_Traits.h"
|
|
#include "ace/RW_Thread_Mutex.h"
|
|
#include "ace/OS_NS_sys_stat.h"
|
|
|
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
|
|
|
enum ACE_Filecache_Flag
|
|
{
|
|
ACE_NOMAP = 0,
|
|
ACE_MAPIT = 1
|
|
};
|
|
|
|
class ACE_Filecache_Object;
|
|
|
|
/**
|
|
* @class ACE_Filecache_Handle
|
|
*
|
|
* @brief
|
|
* Abstraction over a real file. This is meant to be the entry
|
|
* point into the Cached Virtual Filesystem.
|
|
*
|
|
* This is a cached filesystem implementation based loosely on the
|
|
* implementation of JAWS_File. The interfaces will be nearly the
|
|
* same. The under-the-hood implementation should hopefully be a
|
|
* much faster thing.
|
|
* These will be given their own implementations later. For now, we
|
|
* borrow the implementation provided by JAWS.
|
|
* On creation, the cache is checked, and reference count is
|
|
* incremented. On destruction, reference count is decremented. If
|
|
* the reference count is 0, the file is removed from the cache.
|
|
* E.g. 1,
|
|
* {
|
|
* ACE_Filecache_Handle foo("foo.html");
|
|
* this->peer ().send (foo.address (), foo.size ());
|
|
* }
|
|
* E.g. 2,
|
|
* {
|
|
* ACE_Filecache_Handle foo("foo.html");
|
|
* io->transmitfile (foo.handle (), this->peer ().handle ());
|
|
* }
|
|
* E.g. 3,
|
|
* {
|
|
* ACE_Filecache_Handle foo("foo.html", content_length);
|
|
* this->peer ().recv (foo.address (), content_length);
|
|
* }
|
|
* TODO:
|
|
*/
|
|
class ACE_Export ACE_Filecache_Handle
|
|
{
|
|
// (1) Get rid of the useless copying of files when reading.
|
|
// Although it does make sure the file you send isn't being changed,
|
|
// it doesn't make sure the file is in a sensible state before
|
|
// sending it.
|
|
//
|
|
// Alternative: if the file get's trashed while it is being shipped,
|
|
// let the client request the file again. The cache should have an
|
|
// updated copy by that point.
|
|
//
|
|
// (2) Use hashing for locating files. This means I need a hastable
|
|
// implementation with buckets.
|
|
//
|
|
// (3) Only lock when absolutely necessary. JAWS_Virtual_Filesystem was
|
|
// rather conservative, but for some reason it still ran into problems.
|
|
// Since this design should be simpler, problems should be easier to spot.
|
|
//
|
|
public:
|
|
|
|
/// Query cache for file, and acquire it. Assumes the file is being
|
|
/// opened for reading.
|
|
ACE_Filecache_Handle (const ACE_TCHAR *filename,
|
|
ACE_Filecache_Flag mapit = ACE_MAPIT);
|
|
|
|
/**
|
|
* Create new entry, and acquire it. Presence of SIZE assumes the
|
|
* file is being opened for writing. If SIZE is zero, assumes the
|
|
* file is to be removed from the cache.
|
|
*/
|
|
ACE_Filecache_Handle (const ACE_TCHAR *filename,
|
|
int size,
|
|
ACE_Filecache_Flag mapit = ACE_MAPIT);
|
|
|
|
/// Closes any open handles, release acquired file.
|
|
~ACE_Filecache_Handle (void);
|
|
|
|
/// Base address of memory mapped file.
|
|
void *address (void) const;
|
|
|
|
/// A handle (e.g., UNIX file descriptor, or NT file handle).
|
|
ACE_HANDLE handle (void) const;
|
|
|
|
/// Any associated error in handle creation and acquisition.
|
|
int error (void) const;
|
|
|
|
/// The size of the file.
|
|
ACE_OFF_T size (void) const;
|
|
|
|
protected:
|
|
/// Default do nothing constructor. Prevent it from being called.
|
|
ACE_Filecache_Handle (void);
|
|
|
|
/// Common initializations for constructors.
|
|
void init (void);
|
|
|
|
public:
|
|
/// These come from ACE_Filecache_Object, which is an internal class.
|
|
enum
|
|
{
|
|
ACE_SUCCESS = 0,
|
|
ACE_ACCESS_FAILED,
|
|
ACE_OPEN_FAILED,
|
|
ACE_COPY_FAILED,
|
|
ACE_STAT_FAILED,
|
|
ACE_MEMMAP_FAILED,
|
|
ACE_WRITE_FAILED
|
|
};
|
|
|
|
private:
|
|
/// A reference to the low level instance.
|
|
ACE_Filecache_Object *file_;
|
|
|
|
/// A dup'd version of the one from file_.
|
|
ACE_HANDLE handle_;
|
|
};
|
|
|
|
typedef ACE_Hash_Map_Manager_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>
|
|
ACE_Filecache_Hash;
|
|
|
|
typedef ACE_Hash_Map_Entry<const ACE_TCHAR *, ACE_Filecache_Object *> ACE_Filecache_Hash_Entry;
|
|
|
|
/**
|
|
* @class ACE_Filecache
|
|
*
|
|
* @brief
|
|
* A hash table holding the information about entry point into
|
|
* the Cached Virtual Filesystem. On insertion, the reference
|
|
* count is incremented. On destruction, reference count is
|
|
* decremented.
|
|
*/
|
|
class ACE_Export ACE_Filecache
|
|
{
|
|
public:
|
|
/// Singleton pattern.
|
|
static ACE_Filecache *instance (void);
|
|
|
|
~ACE_Filecache (void);
|
|
|
|
/// Returns 0 if the file associated with ``filename'' is in the cache,
|
|
/// or -1 if not.
|
|
int find (const ACE_TCHAR *filename);
|
|
|
|
/// Return the file associated with ``filename'' if it is in the cache,
|
|
/// or create if not.
|
|
ACE_Filecache_Object *fetch (const ACE_TCHAR *filename, int mapit = 1);
|
|
|
|
/// Remove the file associated with ``filename'' from the cache.
|
|
ACE_Filecache_Object *remove (const ACE_TCHAR *filename);
|
|
|
|
/// Create a new Filecache_Object, returns it.
|
|
ACE_Filecache_Object *create (const ACE_TCHAR *filename, int size);
|
|
|
|
/// Release an acquired Filecache_Object, returns it again or NULL if it
|
|
/// was deleted.
|
|
ACE_Filecache_Object *finish (ACE_Filecache_Object *&new_file);
|
|
|
|
protected:
|
|
ACE_Filecache_Object *insert_i (const ACE_TCHAR *filename,
|
|
ACE_SYNCH_RW_MUTEX &filelock,
|
|
int mapit);
|
|
ACE_Filecache_Object *remove_i (const ACE_TCHAR *filename);
|
|
ACE_Filecache_Object *update_i (const ACE_TCHAR *filename,
|
|
ACE_SYNCH_RW_MUTEX &filelock,
|
|
int mapit);
|
|
|
|
public:
|
|
|
|
enum
|
|
{
|
|
/// For this stupid implementation, use an array. Someday, use a
|
|
/// balanced search tree, or real hash table.
|
|
ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE = 512,
|
|
|
|
/// This determines the highwater mark in megabytes for the cache.
|
|
/// This will be ignored for now.
|
|
ACE_DEFAULT_VIRTUAL_FILESYSTEM_CACHE_SIZE = 20
|
|
};
|
|
|
|
protected:
|
|
/// Prevent it from being called.
|
|
ACE_Filecache (void);
|
|
|
|
private:
|
|
ACE_OFF_T size_;
|
|
|
|
/// The hash table
|
|
ACE_Filecache_Hash hash_;
|
|
|
|
/// The reference to the instance
|
|
static ACE_Filecache *cvf_;
|
|
|
|
// = Synchronization variables.
|
|
ACE_SYNCH_RW_MUTEX hash_lock_[ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE];
|
|
ACE_SYNCH_RW_MUTEX file_lock_[ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE];
|
|
};
|
|
|
|
/**
|
|
* @class ACE_Filecache_Object
|
|
*
|
|
* @brief
|
|
* Abstraction over a real file. This is what the Virtual
|
|
* Filesystem contains. This class is not intended for general
|
|
* consumption. Please consult a physician before attempting to
|
|
* use this class.
|
|
*/
|
|
class ACE_Export ACE_Filecache_Object
|
|
{
|
|
public:
|
|
friend class ACE_Filecache;
|
|
|
|
/// Creates a file for reading.
|
|
ACE_Filecache_Object (const ACE_TCHAR *filename,
|
|
ACE_SYNCH_RW_MUTEX &lock,
|
|
LPSECURITY_ATTRIBUTES sa = 0,
|
|
int mapit = 1);
|
|
|
|
/// Creates a file for writing.
|
|
ACE_Filecache_Object (const ACE_TCHAR *filename,
|
|
ACE_OFF_T size,
|
|
ACE_SYNCH_RW_MUTEX &lock,
|
|
LPSECURITY_ATTRIBUTES sa = 0);
|
|
|
|
/// Only if reference count is zero should this be called.
|
|
~ACE_Filecache_Object (void);
|
|
|
|
/// Increment the reference_count_.
|
|
int acquire (void);
|
|
|
|
/// Decrement the reference_count_.
|
|
int release (void);
|
|
|
|
// = error_ accessors
|
|
int error (void) const;
|
|
int error (int error_value,
|
|
const ACE_TCHAR *s = ACE_TEXT ("ACE_Filecache_Object"));
|
|
|
|
/// filename_ accessor
|
|
const ACE_TCHAR *filename (void) const;
|
|
|
|
/// handle_ accessor.
|
|
ACE_HANDLE handle (void) const;
|
|
|
|
/// Base memory address for memory mapped file.
|
|
void *address (void) const;
|
|
|
|
/// size_ accessor.
|
|
ACE_OFF_T size (void) const;
|
|
|
|
/// True if file on disk is newer than cached file.
|
|
int update (void) const;
|
|
|
|
protected:
|
|
/// Prevent from being called.
|
|
ACE_Filecache_Object (void);
|
|
|
|
/// Common initialization code,
|
|
void init (void);
|
|
|
|
private:
|
|
/// Internal error logging method, no locking.
|
|
int error_i (int error_value,
|
|
const ACE_TCHAR *s = ACE_TEXT ("ACE_Filecache_Object"));
|
|
|
|
public:
|
|
|
|
enum Creation_States
|
|
{
|
|
ACE_READING = 1,
|
|
ACE_WRITING = 2
|
|
};
|
|
|
|
enum Error_Conditions
|
|
{
|
|
ACE_SUCCESS = 0,
|
|
ACE_ACCESS_FAILED,
|
|
ACE_OPEN_FAILED,
|
|
ACE_COPY_FAILED,
|
|
ACE_STAT_FAILED,
|
|
ACE_MEMMAP_FAILED,
|
|
ACE_WRITE_FAILED
|
|
};
|
|
|
|
private:
|
|
/// The temporary file name and the real file name. The real file is
|
|
/// copied into the temporary file for safety reasons.
|
|
ACE_TCHAR *tempname_;
|
|
ACE_TCHAR filename_[MAXPATHLEN + 1];
|
|
|
|
/// Holds the memory mapped version of the temporary file.
|
|
ACE_Mem_Map mmap_;
|
|
|
|
/// The descriptor to the temporary file.
|
|
ACE_HANDLE handle_;
|
|
|
|
/// Used to compare against the real file to test if an update is needed.
|
|
ACE_stat stat_;
|
|
ACE_OFF_T size_;
|
|
|
|
/// Status indicators.
|
|
int action_;
|
|
int error_;
|
|
|
|
/// If set to 1, means the object is flagged for removal.
|
|
int stale_;
|
|
|
|
/// Security attribute object.
|
|
LPSECURITY_ATTRIBUTES sa_;
|
|
|
|
/// The default initializer
|
|
ACE_SYNCH_RW_MUTEX junklock_;
|
|
|
|
/// Provides a bookkeeping mechanism for users of this object.
|
|
ACE_SYNCH_RW_MUTEX &lock_;
|
|
};
|
|
|
|
ACE_END_VERSIONED_NAMESPACE_DECL
|
|
|
|
#include /**/ "ace/post.h"
|
|
|
|
#endif /* ACE_FILECACHE_H */
|