Малая механизация: Database.
От: c-smile Канада http://terrainformatica.com
Дата: 04.04.03 01:10
Оценка: 84 (6)
Пример использования:

Вот такая вот база данных:


    struct my_record 
    {
      int  x;
      int  y;
      my_record(): x(0),y(0) {}
    };


    tool::table<my_record> db;
    db.open("c:/test.db",true);
   
    db[0].x = 10;
    db[0].y = 10;

    db[1].x = 20;
    db[1].y = 20;

    ...

    db.close();


Собственно persistent flat table


namespace tool {

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

template<class RECORD>
  class table 
  {
    bool      read_only;

    HANDLE    hfile;
    HANDLE    hmap;

    RECORD*       data;
    unsigned int  total_records;

  public:
    table(): hfile(0),hmap(0),data(0),total_records(0), read_only(true) {}
    virtual ~table() { close(); }

    bool         open(const char *path, bool to_write = false);
    void         close();

    unsigned int total() { return total_records; }
    void         total(unsigned int numrecs) 
            { 
              assert(numrecs <= total_records);
              total_records = numrecs; 
            }

    const RECORD& operator[](int idx) const 
    { 
      assert(idx < total_records);
      return data[idx]; 
    }
    RECORD& operator[](int idx)  
    { 
      assert(!read_only);
      if(idx >= total_records)
      {
        RECORD nullrec;
        while(idx >= total_records)
          data[total_records++] = nullrec;
      }
      return data[idx]; 
    }
  };

  
template <class RECORD>
  inline bool
    table<RECORD>::open(const char *path, bool to_write)
  {
    read_only = !to_write;

    hfile = INVALID_HANDLE_VALUE;
    hmap = INVALID_HANDLE_VALUE;
    data = 0;
    size_t length = 0;
   
    hfile = CreateFile(path, GENERIC_READ | (read_only? 0: GENERIC_WRITE), FILE_SHARE_READ | (read_only? 0: FILE_SHARE_WRITE), NULL,
      read_only?OPEN_EXISTING:CREATE_ALWAYS, 
      FILE_ATTRIBUTE_NORMAL, NULL);
    if (hfile != INVALID_HANDLE_VALUE) 
    {
        length = GetFileSize(hfile, 0);
        hmap = CreateFileMapping(hfile, NULL, read_only? PAGE_READONLY : PAGE_READWRITE, 0, read_only?0:0x10000000, NULL);
    }
    else
    {
      DWORD erno = GetLastError();
      printf("ERROR: memory map file open <%s> failed with %x\n",path, erno);
      return false;
    }
    if (hfile != INVALID_HANDLE_VALUE && hmap == NULL)
    {
        close();
        return false;
    }
    else
    {
        if (hmap != NULL)
          data = (RECORD *) MapViewOfFile(hmap, read_only? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0);
        if(data == 0)
        {
          DWORD erno = GetLastError();
          printf("ERROR: map file %x\n", erno);
          close();
          return false;
        }
    }
    total_records = length / sizeof(RECORD);
    return true;
}


template <class RECORD>
  inline void
    table<RECORD>::close()
{
  if (hfile && hmap && data) {

      if(!read_only)
        if (!FlushViewOfFile(data, total_records * sizeof(RECORD)) ) 
        { 
            printf("Could not flush memory to disk.\n"); 
        } 
      UnmapViewOfFile(data);
      data = 0;
  }
  if (hmap) {
      CloseHandle(hmap);
      hmap = 0;
  }
  if (hfile != INVALID_HANDLE_VALUE)
  {
      if(!read_only)
      {
        SetFilePointer(hfile,total_records * sizeof(RECORD),0,FILE_BEGIN);
        SetEndOfFile(hfile);
      }
      CloseHandle(hfile);
      hfile = 0;
  }
}

}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.