source: tags/0.55/tmp/gdbm_pool.cpp @ 9

Last change on this file since 9 was 9, checked in by willem, 11 years ago

willem

File size: 6.4 KB
Line 
1#include <iostream>
2#include <string>
3#include <sstream>
4#include <iomanip>
5#include "gdbm_pool.h"
6#include "gdbm.h"
7#include <string.h>
8#include <stdlib.h>
9#include "utils.h"
10
11gdbm_pool::gdbm_pool()
12{
13  this->statuskey = "status";
14  this->genkey(this->zerokey,(intkeytype)0);
15  this->file_name = 0;
16}
17
18gdbm_pool::~gdbm_pool()
19{
20  if (this->file_name)
21    free(this->file_name);
22}
23
24#if 0
25void gdbm_pool::genkey(charkeytype key,const intkeytype n)
26{
27  std::ostringstream s;
28  s << std::setfill('0');
29  s << std::setw(keylen-1) << n << '\0';
30  strncpy(key,s.str().c_str(),this->keylen);
31}
32
33#endif
34void gdbm_pool::genkey(charkeytype &key,const charkeytype n)
35{
36  key = n;
37}
38
39void gdbm_pool::set_file_name(std::string filename)
40{
41  this->file_name = strdup(filename.c_str());
42}
43std::string gdbm_pool::get_file_name(void)
44{
45  std::string s(this->file_name);
46  return s;
47}
48
49int gdbm_pool::create_db(void)
50{
51  if (this->file_name == 0)
52    return NOFILENAME;
53
54  dbf = gdbm_open(this->file_name,0,GDBM_NEWDB|this->sync,0644,0);
55
56  if (dbf == 0)
57    return this->OPENERROR;
58
59  genkey(zero.count,this->zerokey);
60  genkey(zero.next,this->zerokey);
61  genkey(zero.last,this->zerokey);
62  genkey(zero.first,this->zerokey);
63
64  int rc = put_zero();
65
66  if (rc != 0)
67  {
68    this->close_db();
69    return this->STOREERROR;
70  }
71  //this->close_db();
72  return 0;
73}
74
75int gdbm_pool::add_line(std::string line)
76{
77
78  int rc = 0;
79  //rc = this->open_db('w');
80  if (rc != 0)
81    return rc;
82  rc = get_zero();
83  if (rc != 0)
84    goto byebye;
85
86  intkeytype last,recordnum;
87
88  //stsd::istringstream(this->zero.last) >> last;
89  last = zero.last;
90  recordnum = last + 1; // the number of the record to store
91
92  // modify last record, only if last != 0
93
94  if (last != 0)
95  {
96    datarecord lastrecord;
97    rc = this->get_record(lastrecord,zero.last);
98    if (rc !=0)
99      goto byebye;
100    this->genkey(lastrecord.next,recordnum);
101    rc = this->put_record(lastrecord,this->zero.last);
102    std::cerr << "WTD: lastrecord:  " << zero.last << ":"<< lastrecord.prev << " " << lastrecord.next <<
103    " " << lastrecord.retrieved << std::endl;
104    if (rc !=0)
105      goto byebye;
106  }
107  // modify zero record
108  this->genkey(this->zero.last,recordnum);
109  this->genkey(this->zero.count,recordnum);
110  intkeytype first;
111
112  //std::istringstream(this->zero.first) >> first;
113  first = zero.first;
114  if (first == 0)
115    this->genkey(this->zero.first,recordnum);
116  intkeytype next;
117  //std::istringstream(this->zero.next) >> next;
118  next = zero.next;
119  if (next == 0)
120    this->genkey(this->zero.next,recordnum);
121  rc = this->put_zero();
122  if (rc != 0)
123  {
124    rc = this->STOREERROR;
125    goto byebye;
126  }
127
128  // now put the line in the database
129  struct datarecord data;
130  genkey(data.prev,last);
131  genkey(data.next,this->zerokey);
132  genkey(data.retrieved,this->zerokey);
133
134  strncpy(data.value,line.c_str(),maxvallen-1);
135  data.value[maxvallen-1] = 0;
136
137  charkeytype k;
138  this->genkey(k,recordnum);
139
140    std::cerr << "WTD: datarecord:  " << k << ":" << data.prev << " " << data.next <<
141    " " << data.retrieved << std::endl;
142  rc = put_record(data,k);
143
144  if (rc != 0)
145  {
146    rc = this->STOREERROR;
147    goto byebye;
148  }
149
150byebye:
151  //this->close_db();
152  return rc;
153}
154
155int gdbm_pool::get_zero(void)
156{
157
158  datum key, content;
159  // create record with key zero
160  key.dptr = &this->zerokey;
161  key.dsize = this->keylen;
162
163  content=gdbm_fetch(this->dbf,key);
164  if (content.dptr == 0)
165    return FETCHERROR;
166  this->zero = *(struct zerorecord *) content.dptr;
167  free(content.dptr);
168  return 0;
169}
170
171int gdbm_pool::put_zero(void)
172{
173  datum key, content;
174  charkeytype k;
175  genkey(k,this->zerokey);
176  key.dptr = &k;
177  key.dsize = keylen;
178  content.dptr = &zero;
179  content.dsize = sizeof(zero);
180  return gdbm_store(this->dbf, key, content, GDBM_REPLACE);
181}
182
183int gdbm_pool::open_db(char rw)
184{
185  if (this->file_name == 0)
186    return this->NOFILENAME;
187  switch (rw)
188  {
189    case 'r':
190      do
191      {
192        dbf = gdbm_open(this->file_name,0,GDBM_READER,0644,0);
193        if (dbf == 0)
194          usleep(1000);
195      }
196      while (dbf == 0);
197      break;
198    case 'w':
199      do
200      {
201        std::cerr << "opening " << this->file_name << std::endl;
202        dbf = gdbm_open(this->file_name,0,GDBM_WRCREAT|this->sync,0644,0);
203        if (dbf == 0)
204          usleep(1000);
205      }
206      while (dbf == 0);
207    break;
208    default:
209      break;
210  }
211  return 0;
212}
213
214int gdbm_pool::close_db(void)
215{
216  gdbm_close(this->dbf);
217  return 0;
218}
219
220int gdbm_pool::get_record(datarecord &r, charkeytype &k)
221{
222  datum key,content;
223  key.dptr = &k;
224  key.dsize = keylen;
225 
226  content=gdbm_fetch(this->dbf,key);
227  if (content.dptr == 0)
228    return this->FETCHERROR;
229  memcpy(&r,content.dptr,content.dsize);
230  free(content.dptr);
231  return 0;
232}
233
234int gdbm_pool::put_record(datarecord &r, charkeytype &k)
235{
236  datum key, content;
237  key.dptr = &k;
238  key.dsize = keylen;
239  int lr = sizeof(r.value) + 1;
240#if 0
241  char buffer[sizeof(r.prev)+sizeof(r.next)+sizeof(r.retrieved) + lr];
242  int p=0;
243  memcpy(&buffer[p],r.prev,sizeof(r.prev));
244  p += sizeof(r.prev);
245  memcpy(&buffer[p],r.next,sizeof(r.next));
246  p += sizeof(r.next);
247  memcpy(&buffer[p],r.retrieved,sizeof(r.retrieved));
248  p += sizeof(r.retrieved);
249  memcpy(&buffer[p],r.value,lr);
250  p += lr;
251  content.dptr = (char*)buffer;
252  content.dsize = p;
253#endif
254  content.dptr = &r;
255  content.dsize = sizeof(r.prev)+ sizeof(r.next)+sizeof(r.retrieved)+lr;
256  return gdbm_store(this->dbf, key, content, GDBM_REPLACE);
257}
258
259int gdbm_pool::get_line(std::string &line)
260{
261  int rc;
262  rc = this->get_zero();
263  if (rc != 0)
264    return FETCHERROR;
265
266  struct datarecord r;
267 
268  intkeytype next;
269  //std::istringstream(this->zero.next) >> next;
270  next = zero.next;
271  if (next == 0)
272    return  NOTFOUND;
273  this->get_record(r,zero.next);
274  std::cerr << "WTD: record: get  " << zero.next << ":" <<r.prev << " " << r.next <<
275    " " << r.retrieved << std::endl;
276
277  line = r.value;
278
279  // adjust the 'retrieved' field of r, and write it
280
281  intkeytype retr;
282  //std::istringstream(r.retrieved) >> retr;
283  retr = r.retrieved;
284  genkey(r.retrieved,retr+1);
285
286  rc = this->put_record(r,zero.next);
287  if (rc != 0)
288    return STOREERROR;
289
290  // adjust the 'next' field of zero. this must be equal
291  // to the 'next' field of r
292
293  this->genkey(this->zero.next,r.next);
294
295  this->put_zero();
296  std::cerr << "WTD: zero in get_:"
297    << zero.next << " " << zero.first << " " <<
298      zero.last << " " << zero.count << std::endl;
299
300  std::cerr << "WTD: record:      " << zero.next << ":" <<r.prev << " " << r.next <<
301    " " << r.retrieved << std::endl;
302
303  return 0;
304}
Note: See TracBrowser for help on using the repository browser.