summaryrefslogtreecommitdiff
path: root/ACE/ace/Filecache.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Filecache.h')
-rw-r--r--ACE/ace/Filecache.h353
1 files changed, 353 insertions, 0 deletions
diff --git a/ACE/ace/Filecache.h b/ACE/ace/Filecache.h
new file mode 100644
index 00000000000..df1835b9372
--- /dev/null
+++ b/ACE/ace/Filecache.h
@@ -0,0 +1,353 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Filecache.h
+ *
+ * $Id$
+ *
+ * @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_;
+
+ int mapit_;
+};
+
+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 */