Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
1st1 committed Dec 7, 2024
1 parent f86f256 commit 00650b0
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 65 deletions.
25 changes: 24 additions & 1 deletion edgedb/datatypes/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,29 @@ PyObject * EdgeObject_GetRecordDesc(PyObject *);
int EdgeObject_SetItem(PyObject *, Py_ssize_t, PyObject *);
PyObject * EdgeObject_GetItem(PyObject *, Py_ssize_t);

PyObject * EdgeObject_GetID(PyObject *ob);

/* === edgedb.Record ======================================== */

#define EDGE_RECORD_FREELIST_SIZE 2000
#define EDGE_RECORD_FREELIST_MAXSAVE 20

extern PyTypeObject EdgeRecord_Type;

#define EdgeRecord_Check(d) (Py_TYPE(d) == &EdgeRecord_Type)

typedef struct {
PyObject_VAR_HEAD
PyObject *weakreflist;
PyObject *desc;
Py_hash_t cached_hash;
PyObject *ob_item[1];
} EdgeRecord;

PyObject * EdgeRecord_InitType(void);
PyObject * EdgeRecord_New(PyObject *);
PyObject * EdgeRecord_GetRecordDesc(PyObject *);

int EdgeRecord_SetItem(PyObject *, Py_ssize_t, PyObject *);
PyObject * EdgeRecord_GetItem(PyObject *, Py_ssize_t);

#endif
4 changes: 4 additions & 0 deletions edgedb/datatypes/datatypes.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ cdef extern from "datatypes.h":
int EdgeObject_SetItem(object, Py_ssize_t, object) except -1
object EdgeObject_GetRecordDesc(object)

object EdgeRecord_InitType()
object EdgeRecord_New(object);
int EdgeRecord_SetItem(object, Py_ssize_t, object) except -1
object EdgeRecord_GetRecordDesc(object)

cdef record_desc_new(object names, object flags, object cards)
cdef record_desc_pointer_name(object desc, Py_ssize_t pos)
Expand Down
8 changes: 7 additions & 1 deletion edgedb/datatypes/datatypes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ _RecordDescriptor = EdgeRecordDesc_InitType()
Tuple = tuple
NamedTuple = EdgeNamedTuple_InitType()
Object = EdgeObject_InitType()
Record = EdgeRecord_InitType()
Set = list
Array = list

Expand Down Expand Up @@ -132,6 +133,11 @@ cdef namedtuple_type_new(object desc):
cdef object_new(object desc):
return EdgeObject_New(desc)


cdef object_set(object obj, Py_ssize_t pos, object elem):
EdgeObject_SetItem(obj, pos, elem)

cdef record_new(object desc):
return EdgeRecord_New(desc)

cdef record_set(object obj, Py_ssize_t pos, object elem):
EdgeRecord_SetItem(obj, pos, elem)
19 changes: 0 additions & 19 deletions edgedb/datatypes/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,25 +124,6 @@ EdgeObject_GetItem(PyObject *ob, Py_ssize_t i)
}


PyObject *
EdgeObject_GetID(PyObject *ob)
{
assert(EdgeObject_Check(ob));
EdgeObject *o = (EdgeObject *)ob;
Py_ssize_t i = EdgeRecordDesc_IDPos(o->desc);
if (i < 0) {
Py_RETURN_NONE;
}
if (i >= Py_SIZE(o)) {
PyErr_BadInternalCall();
return NULL;
}
PyObject *el = EdgeObject_GET_ITEM(o, i);
Py_INCREF(el);
return el;
}


static void
object_dealloc(EdgeObject *o)
{
Expand Down
221 changes: 221 additions & 0 deletions edgedb/datatypes/record.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#include "pythoncapi_compat.h"

/*
* This source file is part of the EdgeDB open source project.
*
* Copyright 2016-present MagicStack Inc. and the EdgeDB authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


#include "datatypes.h"
#include "freelist.h"
#include "internal.h"


static int init_type_called = 0;

EDGE_SETUP_FREELIST(
EDGE_RECORD,
EdgeRecord,
EDGE_RECORD_FREELIST_MAXSAVE,
EDGE_RECORD_FREELIST_SIZE)


#define EdgeRecord_GET_ITEM(op, i) \
(((EdgeRecord *)(op))->ob_item[i])
#define EdgeRecord_SET_ITEM(op, i, v) \
(((EdgeRecord *)(op))->ob_item[i] = v)


PyObject *
EdgeRecord_New(PyObject *desc)
{
assert(init_type_called);

if (desc == NULL || !EdgeRecordDesc_Check(desc)) {
PyErr_BadInternalCall();
return NULL;
}

Py_ssize_t size = EdgeRecordDesc_GetSize(desc);

if (size > EDGE_MAX_TUPLE_SIZE) {
PyErr_Format(
PyExc_ValueError,
"Cannot create Object with more than %d elements",
EDGE_MAX_TUPLE_SIZE);
return NULL;
}

EdgeRecord *o = NULL;
EDGE_NEW_WITH_FREELIST(EDGE_RECORD, EdgeRecord,
&EdgeRecord_Type, o, size);
assert(o != NULL);
assert(Py_SIZE(o) == size);
assert(EdgeRecord_Check(o));

o->weakreflist = NULL;

Py_INCREF(desc);
o->desc = desc;

o->cached_hash = -1;

PyObject_GC_Track(o);
return (PyObject *)o;
}


PyObject *
EdgeRecord_GetRecordDesc(PyObject *o)
{
if (!EdgeRecord_Check(o)) {
PyErr_Format(
PyExc_TypeError,
"an instance of edgedb.Object expected");
return NULL;
}

PyObject *desc = ((EdgeRecord *)o)->desc;
Py_INCREF(desc);
return desc;
}


int
EdgeRecord_SetItem(PyObject *ob, Py_ssize_t i, PyObject *el)
{
assert(EdgeRecord_Check(ob));
EdgeRecord *o = (EdgeRecord *)ob;
assert(i >= 0);
assert(i < Py_SIZE(o));
Py_INCREF(el);
EdgeRecord_SET_ITEM(o, i, el);
return 0;
}


PyObject *
EdgeRecord_GetItem(PyObject *ob, Py_ssize_t i)
{
assert(EdgeRecord_Check(ob));
EdgeRecord *o = (EdgeRecord *)ob;
if (i < 0 || i >= Py_SIZE(o)) {
PyErr_BadInternalCall();
return NULL;
}
PyObject *el = EdgeRecord_GET_ITEM(o, i);
Py_INCREF(el);
return el;
}


static void
record_dealloc(EdgeRecord *o)
{
PyObject_GC_UnTrack(o);
if (o->weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*)o);
}
Py_CLEAR(o->desc);
o->cached_hash = -1;
Py_TRASHCAN_BEGIN(o, record_dealloc);
EDGE_DEALLOC_WITH_FREELIST(EDGE_RECORD, EdgeRecord, o);
Py_TRASHCAN_END(o);
}


static int
record_traverse(EdgeRecord *o, visitproc visit, void *arg)
{
Py_VISIT(o->desc);

Py_ssize_t i;
for (i = Py_SIZE(o); --i >= 0;) {
if (o->ob_item[i] != NULL) {
Py_VISIT(o->ob_item[i]);
}
}
return 0;
}


static PyObject *
record_getitem(EdgeRecord *o, PyObject *name)
{
Py_RETURN_NONE;
}


static PyObject *
record_repr(EdgeRecord *o)
{
_PyUnicodeWriter writer;
_PyUnicodeWriter_Init(&writer);
writer.overallocate = 1;

if (_PyUnicodeWriter_WriteASCIIString(&writer, "Object{", 7) < 0) {
goto error;
}

if (_EdgeGeneric_RenderItems(&writer,
(PyObject *)o, o->desc,
o->ob_item, Py_SIZE(o), 1, 0) < 0)
{
goto error;
}

if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0) {
goto error;
}

return _PyUnicodeWriter_Finish(&writer);

error:
_PyUnicodeWriter_Dealloc(&writer);
return NULL;
}


static PyMappingMethods record_as_mapping = {
.mp_subscript = (binaryfunc)record_getitem,
};


PyTypeObject EdgeRecord_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"edgedb.Record",
.tp_basicsize = sizeof(EdgeRecord) - sizeof(PyObject *),
.tp_itemsize = sizeof(PyObject *),
.tp_dealloc = (destructor)record_dealloc,
.tp_as_mapping = &record_as_mapping,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_traverse = (traverseproc)record_traverse,
.tp_free = PyObject_GC_Del,
.tp_repr = (reprfunc)record_repr,
.tp_weaklistoffset = offsetof(EdgeRecord, weakreflist),
};


PyObject *
EdgeRecord_InitType(void)
{
if (PyType_Ready(&EdgeRecord_Type) < 0) {
return NULL;
}

init_type_called = 1;
return (PyObject *)&EdgeRecord_Type;
}
11 changes: 7 additions & 4 deletions edgedb/protocol/codecs/codecs.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ include "./scalar.pxd"
include "./tuple.pxd"
include "./namedtuple.pxd"
include "./object.pxd"
include "./record.pxd"
include "./array.pxd"
include "./range.pxd"
include "./set.pxd"
Expand All @@ -35,9 +36,11 @@ cdef class CodecsRegistry:
LRUMapping codecs
dict base_codec_overrides

cdef BaseCodec _build_codec(self, FRBuffer *spec, list codecs_list,
cdef BaseCodec _build_codec(self, InputLanguage lang,
FRBuffer *spec, list codecs_list,
protocol_version)
cdef BaseCodec build_codec(self, bytes spec, protocol_version)
cdef BaseCodec build_codec(self, InputLanguage lang, bytes spec,
protocol_version)

cdef has_codec(self, bytes type_id)
cdef BaseCodec get_codec(self, bytes type_id)
cdef has_codec(self, InputLanguage lang, bytes type_id)
cdef BaseCodec get_codec(self, InputLanguage lang, bytes type_id)
Loading

0 comments on commit 00650b0

Please sign in to comment.