#ifndef COUNT_MIN_H #define COUNT_MIN_H /*******************************************************/ /* Inherited Linear sketch/ countmin declarations */ /*******************************************************/ typedef struct { LinearSketch super; // inherits from the linear sketch class uint32_t* hash_table; // table storing random bits that acts as hash function uint32_t* X; uint8_t hash_bit : 1; uint16_t seed; } CountMin; static void CountMin_dealloc(CountMin*); static PyObject *CountMin_new(PyTypeObject*, PyObject *, PyObject *); static int CountMin_init(CountMin *, PyObject *, PyObject *); static PyObject *CountMin_update(CountMin *, PyObject * ); static PyObject *CountMin_query(CountMin *, PyObject * ); static PyObject *CountMin_combine(PyObject *, PyObject *, PyObject *); static PyObject*get_shape(CountMin* , void* ); static PyObject*get_hasher(CountMin*, void* ); static PyObject*get_sketch(CountMin*, void* ); static PyObject* get_shape(CountMin* self, void* closure){ PyObject* shape; float epsilon, delta; uint32_t s,t; epsilon = byte_to_float(self->super.epsilon); delta = byte_to_float(self->super.delta); s = (uint32_t) ceil(2/ (float) epsilon); t = ceil( log2(1/(float) delta)); if(self->hash_bit == 0){ s = nextPrime(s); } if( (shape = PyTuple_Pack(2, PyLong_FromUnsignedLong((unsigned long) t), PyLong_FromUnsignedLong((unsigned long) s))) == NULL){ PyErr_NoMemory(); return Py_None; } return shape; } static PyObject* get_hasher(CountMin* self, void* closure) { const char* s; if(self->hash_bit == 0){ s = "CW"; } else if(self->hash_bit == 1){ s = "mult-shift"; } return Py_BuildValue("s#", s, strlen(s)); } static PyObject* get_sketch(CountMin* self, void* closure){ PyObject* list; float epsilon, delta; uint32_t s,t; epsilon = byte_to_float(self->super.epsilon); delta = byte_to_float(self->super.delta); s = (uint32_t) ceil(2/ (float) epsilon); t = ceil( log2(1/(float) delta)); if(self->hash_bit == 0){ s = nextPrime(s); } list = PyList_New(t); for(uint32_t i = 0; i < t; i++){ PyObject* temp = PyList_New(s); for(uint32_t j = 0; j < s; j++){ PyList_SetItem(temp, j, Py_BuildValue("i", self->X[i*t + j])); } PyList_SetItem(list, i, temp); } return list; } PyGetSetDef get_CountMin_sets[] = { {"shape", /* name */ (getter) get_shape, NULL, NULL, /* doc */ NULL /* closure */}, {"hasher", /* name */ (getter) get_hasher, NULL, NULL, /* doc */ NULL /* closure */}, {"sketch", /* name */ (getter) get_sketch, NULL, NULL, /* doc */ NULL /* closure */}, {NULL} }; static PyMethodDef CountMin_methods[] = { {"update", (PyCFunction) CountMin_update, METH_VARARGS, "Updates the sketch with a new token input from the stream" }, {"query", (PyCFunction) CountMin_query, METH_VARARGS, "Output the counter estimate" }, {"combine", (PyCFunction) CountMin_combine, METH_VARARGS | METH_KEYWORDS, "Combine two CountMin skeches" }, {NULL} /* Sentinel */ }; static PyTypeObject CountMin_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "sketches.CountMin", .tp_doc = "CountMin Sketch class", .tp_basicsize = sizeof(CountMin), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_new = CountMin_new, .tp_init = (initproc)CountMin_init, .tp_dealloc = (destructor)CountMin_dealloc, .tp_methods = CountMin_methods, .tp_base = &LinearSketch_type, .tp_getset = get_CountMin_sets, }; #endif //COUNT_MIN_H