00001
00002
00003
00004 #ifndef AITOOLS_INVERTEDINDEX_ITERATOR_HPP
00005 #define AITOOLS_INVERTEDINDEX_ITERATOR_HPP
00006
00007 #include "Quantile.hpp"
00008 #include "Exception.hpp"
00009 #include "ByteBuffer.hpp"
00010 #include "NonCopyable.hpp"
00011 #include <boost/shared_ptr.hpp>
00012 #include <climits>
00013 #include <cstdio>
00014
00015 namespace aitools {
00016 namespace invertedindex {
00017
00027 class Iterator : public NonCopyable {
00028
00029 public:
00030
00031 typedef uint16_t value_size_t;
00032
00033 typedef std::vector<value_size_t> SizeVector;
00034
00035 typedef boost::shared_ptr<Iterator> SharedPointer;
00036
00037 struct Header
00038 {
00039 Header()
00040 : value_count(0),
00041 value_size(0),
00042 checksum(0),
00043 payload(0)
00044 {}
00045 uint32_t value_count;
00046 uint16_t value_size;
00047 uint16_t checksum;
00048 uint32_t payload;
00049 };
00050
00051 struct Chunk
00052 {
00053 Chunk()
00054 : buffer(new ByteBuffer),
00055 offset(0),
00056 begin(0),
00057 end(0)
00058 {}
00059 Chunk(ByteBuffer* buffer)
00060 : buffer(buffer),
00061 offset(0),
00062 begin(0),
00063 end(0)
00064 {
00065 assert(buffer != NULL);
00066 }
00067 ~Chunk()
00068 {
00069 delete buffer;
00070 }
00071 ByteBuffer* buffer;
00072 size_t offset;
00073 size_t begin;
00074 size_t end;
00075 };
00076
00077 struct Page
00078 {
00079 Page()
00080 : offset(0),
00081 file(NULL)
00082 {}
00083 Page(FILE* file)
00084 : offset(0),
00085 file(file)
00086 {
00087 assert(file != NULL);
00088 offset = std::ftell(file);
00089 }
00090 ~Page()
00091 {
00092 if (file != NULL)
00093 {
00094 std::fclose(file);
00095 file = NULL;
00096 }
00097 }
00098 size_t offset;
00099 FILE* file;
00100 };
00101
00102 public:
00103
00104 static const size_t max_chunk_size = 10 * 1024 * 1024;
00105 static const size_t sizeof_value_size_t = sizeof(value_size_t);
00106 static const size_t sizeof_header = sizeof(Header);
00107
00108 public:
00109
00110 Iterator();
00111
00112 Iterator(const Header& header, FILE* page);
00113
00114 Iterator(const Header& header, ByteBuffer* buffer);
00115
00116 Iterator(const Header& header, SizeVector* value_sizes, FILE* page);
00117
00118 Iterator(const Header& header, SizeVector* value_sizes, ByteBuffer* buffer);
00119
00120 ~Iterator();
00121
00122 public:
00123
00124 void advance();
00125
00126 uint16_t checksum() const;
00127
00128 const Chunk& chunk() const;
00129
00130 const SizeVector& value_sizes() const;
00131
00132 const Header& header() const;
00133
00134 inline bool is_paged() const
00135 {
00136 return page_.file != NULL;
00137 }
00138
00139 inline bool is_valid() const
00140 {
00141 return index_ != header_.value_count;
00142 }
00143
00144 size_t length() const;
00145
00146 size_t payload() const;
00147
00148 void rewind();
00149
00150 inline size_t size() const
00151 {
00152 return header_.value_size ? header_.value_size : (*vsizes_)[index_];
00153 }
00154
00155 bool swap() throw (std::runtime_error);
00156
00157 inline const char* value() const
00158 {
00159 return chunk_.buffer->data() + chunk_.offset;
00160 }
00161
00162 private:
00163
00164 Header header_;
00165 SizeVector* vsizes_;
00166 Chunk chunk_;
00167 Page page_;
00168 size_t index_;
00169
00170 };
00171
00172 }
00173 }
00174
00175 #endif // AITOOLS_INVERTEDINDEX_ITERATOR_HPP