static PyObject* cdb_py_write_header(PyObject* self) { cdb_t *cdb = ((StorageObject*)self)->cdb; if (cdb_write_header(cdb) != CDB_SUCCESS) { PyErr_SetFromErrno(PyExc_IOError); } return self; }
int cdb_discard_records_in_time_range(cdb_t *cdb, cdb_request_t *request, uint64_t *num_recs) { uint64_t i = 0; int64_t lrec; off_t offset = RECORD_SIZE; *num_recs = 0; if (cdb_read_header(cdb) != CDB_SUCCESS) { return cdb_error(); } if (_cdb_is_writable(cdb) == false) { return CDB_ERDONLY; } lrec = _logical_record_for_time(cdb, request->start, 0, 0); if (lrec >= 1) { lrec -= 1; } for (i = lrec; i < cdb->header->num_records; i++) { cdb_time_t rtime = _time_for_logical_record(cdb, i); if (rtime >= request->start && rtime <= request->end) { cdb_record_t record[RECORD_SIZE]; record->time = rtime; record->value = CDB_NAN; if (pwrite(cdb->fd, &record, RECORD_SIZE, offset) != RECORD_SIZE) { return cdb_error(); } *num_recs += 1; } } if (*num_recs > 0) { cdb->synced = false; } if (cdb_write_header(cdb) != CDB_SUCCESS) { return cdb_error(); } return CDB_SUCCESS; }
static int Storage_init(PyObject *self, PyObject *args, PyObject *kwdict) { static char *kwlist[] = { "filename", "flags", "mode", "name", "desc", "max_records", "type", "units", "min_value", "max_value", NULL, }; char *filename; int flags = -1; int mode = -1; char *name = NULL; char *desc = ""; char *type = (char*)_string_from_cdb_type(CDB_DEFAULT_DATA_TYPE); char *units = CDB_DEFAULT_DATA_UNIT; uint64_t max_records = 0; double min_value = 0; double max_value = 0; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s|iiszlzzlli:new", kwlist, &filename, &flags, &mode, &name, &desc, &max_records, &type, &units, &min_value, &max_value)) { return -1; } PyObject *header = ((StorageObject*)self)->header; cdb_t *cdb = ((StorageObject*)self)->cdb; cdb->filename = filename; cdb->flags = flags; cdb->mode = mode; // Try the open if (cdb_open(cdb) != CDB_SUCCESS) { PyErr_SetFromErrno(PyExc_IOError); return -1; } // Try and read a header, if it doesn't exist, create one if (name == NULL) { if (cdb_read_header(cdb) != CDB_SUCCESS) { PyErr_SetFromErrno(PyExc_IOError); return -1; } } else { cdb_generate_header(cdb, name, desc, max_records, _cdb_type_from_string(type), units, min_value, max_value); if (cdb_write_header(cdb) != CDB_SUCCESS) { PyErr_SetFromErrno(PyExc_IOError); return -1; } } PyDict_SetItemString(header, "filename", PyString_FromString(filename)); PyDict_SetItemString(header, "name", PyString_FromString(cdb->header->name)); PyDict_SetItemString(header, "desc", PyString_FromString(cdb->header->desc)); PyDict_SetItemString(header, "type", PyString_FromString(_string_from_cdb_type(cdb->header->type))); PyDict_SetItemString(header, "units", PyString_FromString(cdb->header->units)); PyDict_SetItemString(header, "num_records", PyInt_FromLong(cdb->header->num_records)); PyDict_SetItemString(header, "max_records", PyInt_FromLong(cdb->header->max_records)); PyDict_SetItemString(header, "min_value", PyInt_FromLong(cdb->header->min_value)); PyDict_SetItemString(header, "max_value", PyInt_FromLong(cdb->header->max_value)); return 0; }
int cdb_update_records(cdb_t *cdb, cdb_record_t *records, uint64_t len, uint64_t *num_recs) { int ret = CDB_SUCCESS; *num_recs = 0; uint64_t i = 0; if (cdb_read_header(cdb) != CDB_SUCCESS) { return cdb_error(); } if (_cdb_is_writable(cdb) == false) { return CDB_ERDONLY; } #ifdef DEBUG printf("in update_records with [%"PRIu64"] num_recs\n", cdb->header->num_records); #endif for (i = 0; i < len; i++) { cdb_time_t time = records[i].time; cdb_time_t rtime; uint64_t lrec; lrec = _logical_record_for_time(cdb, time, 0, 0); if (lrec >= 1) { lrec -= 1; /* DRK things like this are extremely confusing. some logical functions are zero based? some are one? or you're trying to back up? */ } rtime = _time_for_logical_record(cdb, lrec); while (rtime < time && lrec < cdb->header->num_records - 1) { /* DRK is this true? or is the condition (lrec - start_lrec) < num_recs -- seems you can't wrap here (i.e. what if the initial lrec was num_recs - 1) */ lrec += 1; rtime = _time_for_logical_record(cdb, lrec); } #ifdef DEBUG printf("update_records: value: lrec [%"PRIu64"] time [%d] rtime [%d]\n", lrec, (int)time, (int)rtime); #endif while (time == rtime && lrec < cdb->header->num_records - 1) { _seek_to_logical_record(cdb, lrec); if (write(cdb->fd, &records[0], RECORD_SIZE) != RECORD_SIZE) { ret = cdb_error(); break; } lrec += 1; rtime = _time_for_logical_record(cdb, lrec); } } if (ret == CDB_SUCCESS) { if (i > 0) { cdb->synced = false; *num_recs = i; } if (cdb_write_header(cdb) != CDB_SUCCESS) { ret = cdb_error(); } } return ret; }
int cdb_write_records(cdb_t *cdb, cdb_record_t *records, uint64_t len, uint64_t *num_recs) { /* read old header if it exists. write a header out, since the db may not have existed. */ uint64_t i = 0; uint64_t j = 0; off_t offset = 0; *num_recs = 0; if (cdb_read_header(cdb) != CDB_SUCCESS) { return cdb_error(); } if (_cdb_is_writable(cdb) == false) { return CDB_ERDONLY; } if (cdb->header->max_records <= 0) { return CDB_EINVMAX; } /* Logic for writes: cdb is 5 records. try to write 7 records len = 7 len + 0 > 5 j = (7 + 0) - 5 j = 2 i = 7 - 2 i = 5 need to write j records at offset: HEADER_SIZE + (cdb->header->start_record * RECORD_SIZE) index into records is i need to write i records at offset: HEADER_SIZE + (cdb->header->num_records * RECORD_SIZE) index into records is 0; */ /* Calculate our indicies into the records array. */ if (len + cdb->header->num_records >= cdb->header->max_records) { j = (len + cdb->header->num_records) - cdb->header->max_records; i = (len - j); } else { i = len; } /* If we need to wrap around */ if (j > 0) { offset = HEADER_SIZE + (cdb->header->start_record * RECORD_SIZE); cdb->header->start_record += j; cdb->header->start_record %= cdb->header->max_records; if (pwrite(cdb->fd, &records[i], (RECORD_SIZE * j), offset) != (RECORD_SIZE * j)) { return cdb_error(); } cdb->synced = false; /* start_record is no longer 0, so update the header */ if (cdb_write_header(cdb) != CDB_SUCCESS) { return cdb_error(); } } /* Normal case */ offset = HEADER_SIZE + (cdb->header->num_records * RECORD_SIZE); cdb->header->num_records += i; if (pwrite(cdb->fd, &records[0], (RECORD_SIZE * i), offset) != (RECORD_SIZE * i)) { return cdb_error(); } *num_recs += len; #ifdef DEBUG printf("write_records: wrote [%"PRIu64"] records\n", *num_recs); #endif return CDB_SUCCESS; }