• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

I_Store.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026   Store.h
00027 
00028 
00029  ****************************************************************************/
00030 
00031 #ifndef _Store_h_
00032 #define _Store_h_
00033 
00034 #include "libts.h"
00035 
00036 #define STORE_BLOCK_SIZE       8192
00037 #define STORE_BLOCK_SHIFT      13
00038 #define DEFAULT_HW_SECTOR_SIZE 512
00039 
00040 //
00041 // A Store is a place to store data.
00042 // Those on the same disk should be in a linked list.
00043 //
00044 struct Span
00045 {
00046   int64_t blocks;
00047   int64_t offset;                 // used only if (file == true)
00048   int hw_sector_size;
00049   int alignment;
00050   int disk_id;
00051   int forced_volume_num;  ///< Force span in to specific volume.
00052 private:
00053     bool is_mmapable_internal;
00054 public:
00055   bool file_pathname;           // the pathname is a file
00056   bool isRaw;
00057   // v- used as a magic location for copy constructor.
00058   // we memcpy everything before this member and do explicit assignment for the rest.
00059   ats_scoped_str pathname;
00060   ats_scoped_str hash_base_string; ///< Used to seed the stripe assignment hash.
00061   SLINK(Span, link);
00062 
00063   bool is_mmapable() { return is_mmapable_internal; }
00064   void set_mmapable(bool s) { is_mmapable_internal = s; }
00065   int64_t size() { return blocks * STORE_BLOCK_SIZE; }
00066 
00067   int64_t total_blocks() {
00068     if (link.next) {
00069       return blocks + link.next->total_blocks();
00070     } else {
00071       return blocks;
00072     }
00073   }
00074 
00075   Span *nth(int i) {
00076     Span *x = this;
00077     while (x && i--)
00078       x = x->link.next;
00079     return x;
00080   }
00081 
00082   int paths() {
00083     int i = 0;
00084     for (Span * x = this; x; i++, x = x->link.next);
00085     return i;
00086   }
00087   int write(int fd);
00088   int read(int fd);
00089 
00090   /// Duplicate this span and all chained spans.
00091   Span *dup();
00092   int64_t end() { return offset + blocks; }
00093 
00094   const char *init(char *n, int64_t size);
00095 
00096   // 0 on success -1 on failure
00097   int path(char *filename,      // for non-file, the filename in the director
00098            int64_t * offset,      // for file, start offset (unsupported)
00099            char *buf, int buflen);      // where to store the path
00100 
00101   /// Set the hash seed string.
00102   void hash_base_string_set(char const* s);
00103   /// Set the volume number.
00104   void volume_number_set(int n);
00105 
00106   Span()
00107     : blocks(0)
00108     , offset(0)
00109     , hw_sector_size(DEFAULT_HW_SECTOR_SIZE)
00110     , alignment(0)
00111     , disk_id(0)
00112     , forced_volume_num(-1)
00113     , is_mmapable_internal(false)
00114     , file_pathname(false)
00115     , isRaw(true)
00116   { }
00117 
00118   /// Copy constructor.
00119   /// @internal Prior to this implementation handling the char* pointers was done manual
00120   /// at every call site. We also need this because we have ats_scoped_str members.
00121   Span(Span const& that) {
00122     memcpy(this, &that, reinterpret_cast<intptr_t>(&(static_cast<Span*>(0)->pathname)));
00123     if (that.pathname) pathname = ats_strdup(that.pathname);
00124     if (that.hash_base_string) hash_base_string = ats_strdup(that.hash_base_string);
00125     link.next = NULL;
00126   }
00127 
00128   ~Span();
00129 };
00130 
00131 struct Store
00132 {
00133   //
00134   // Public Interface
00135   // Thread-safe operations
00136   //
00137 
00138   // spread evenly on all disks
00139   void spread_alloc(Store & s, unsigned int blocks, bool mmapable = true);
00140   void alloc(Store & s, unsigned int blocks, bool only_one = false, bool mmapable = true);
00141 
00142   Span *alloc_one(unsigned int blocks, bool mmapable) {
00143     Store s;
00144       alloc(s, blocks, true, mmapable);
00145     if (s.n_disks)
00146     {
00147       Span *t = s.disk[0];
00148         s.disk[0] = NULL;
00149         return t;
00150     } else
00151         return NULL;
00152   }
00153   // try to allocate, return (s == gotten, diff == not gotten)
00154   void try_realloc(Store & s, Store & diff);
00155 
00156   // free back the contents of a store.
00157   // must have been JUST allocated (no intervening allocs/frees)
00158   void free(Store & s);
00159   void add(Span * s);
00160   void add(Store & s);
00161   void dup(Store & s);
00162   void sort();
00163   void extend(unsigned i)
00164   {
00165     if (i > n_disks) {
00166       disk = (Span **)ats_realloc(disk, i * sizeof(Span *));
00167       for (unsigned j = n_disks; j < i; j++) {
00168         disk[j] = NULL;
00169       }
00170       n_disks = i;
00171     }
00172   }
00173 
00174   // Non Thread-safe operations
00175   unsigned int total_blocks(unsigned after = 0) {
00176     int64_t t = 0;
00177     for (unsigned i = after; i < n_disks; i++) {
00178       if (disk[i]) {
00179         t += disk[i]->total_blocks();
00180       }
00181     }
00182     return (unsigned int) t;
00183   }
00184   // 0 on success -1 on failure
00185   // these operations are NOT thread-safe
00186   //
00187   int write(int fd, char *name);
00188   int read(int fd, char *name);
00189   int clear(char *filename, bool clear_dirs = true);
00190   void normalize();
00191   void delete_all();
00192   int remove(char *pathname);
00193   Store();
00194   ~Store();
00195 
00196   unsigned n_disks;
00197   Span **disk;
00198 #if TS_USE_INTERIM_CACHE == 1
00199   int n_interim_disks;
00200   Span **interim_disk;
00201   const char *read_interim_config();
00202 #endif
00203   //
00204   // returns NULL on success
00205   // if fd >= 0 then on failure it returns an error string
00206   //            otherwise on failure it returns (char *)-1
00207   //
00208   const char *read_config(int fd = -1);
00209   int write_config_data(int fd);
00210 
00211   /// Additional configuration key values.
00212   static char const VOLUME_KEY[];
00213   static char const HASH_BASE_STRING_KEY[];
00214 };
00215 
00216 extern Store theStore;
00217 
00218 // store either free or in the cache, can be stolen for reconfiguration
00219 void stealStore(Store & s, int blocks);
00220 int initialize_store();
00221 
00222 struct storageConfigFile {
00223   const char *parseFile(int fd) {
00224     Store tStore;
00225     return tStore.read_config(fd);
00226   }
00227 };
00228 
00229 #endif

Generated by  doxygen 1.7.1