change ptrsz to ptrs to free up space in capn_ptr

This commit is contained in:
James McKaskill 2013-09-13 10:02:03 -04:00
parent 7397df1216
commit 59f827e93d
5 changed files with 62 additions and 64 deletions

View file

@ -17,7 +17,7 @@ UINT_T CAT(capn_get,SZ) (LIST_T l, int off) {
case CAPN_COMPOSITE_LIST:
if (p.datasz < SZ/8)
return 0;
d = p.data + off * (p.datasz + p.ptrsz);
d = p.data + off * (p.datasz + 8*p.ptrs);
return FLIP(*(UINT_T*)d);
case CAPN_PTR_LIST:
@ -43,7 +43,7 @@ int CAT(capn_getv,SZ) (LIST_T l, int off, UINT_T *to, int sz) {
switch (p.type) {
case CAPN_LIST:
case CAPN_COMPOSITE_LIST:
if (p.datasz == SZ/8 && !p.ptrsz && (SZ == 8 || CAPN_LITTLE)) {
if (p.datasz == SZ/8 && !p.ptrs && (SZ == 8 || CAPN_LITTLE)) {
memcpy(to, p.data + off, sz * (SZ/8));
return sz;
} else if (p.datasz < SZ/8) {
@ -51,7 +51,7 @@ int CAT(capn_getv,SZ) (LIST_T l, int off, UINT_T *to, int sz) {
}
for (i = 0; i < sz; i++) {
char *d = p.data + (i + off) * (p.datasz + p.ptrsz);
char *d = p.data + (i + off) * (p.datasz + 8*p.ptrs);
to[i] = FLIP(*(UINT_T*)d);
}
return sz;
@ -84,7 +84,7 @@ int CAT(capn_set,SZ) (LIST_T l, int off, UINT_T v) {
case CAPN_COMPOSITE_LIST:
if (p.datasz < SZ/8)
return -1;
d = p.data + off * (p.datasz + p.ptrsz);
d = p.data + off * (p.datasz + 8*p.ptrs);
*(UINT_T*) d = FLIP(v);
return 0;
@ -111,7 +111,7 @@ int CAT(capn_setv,SZ) (LIST_T l, int off, const UINT_T *from, int sz) {
switch (p.type) {
case CAPN_LIST:
case CAPN_COMPOSITE_LIST:
if (p.datasz == SZ/8 && !p.ptrsz && (SZ == 8 || CAPN_LITTLE)) {
if (p.datasz == SZ/8 && !p.ptrs && (SZ == 8 || CAPN_LITTLE)) {
memcpy(p.data + off, from, sz * (SZ/8));
return sz;
} else if (p.datasz < SZ/8) {
@ -119,7 +119,7 @@ int CAT(capn_setv,SZ) (LIST_T l, int off, const UINT_T *from, int sz) {
}
for (i = 0; i < sz; i++) {
char *d = p.data + (i + off) * (p.datasz + p.ptrsz);
char *d = p.data + (i + off) * (p.datasz + 8*p.ptrs);
*(UINT_T*) d = FLIP(from[i]);
}
return sz;

View file

@ -49,7 +49,7 @@ TEST(WireFormat, SimpleRawDataStruct) {
struct capn_ptr ptr = capn_getp(capn_root(&ctx), 0, 1);
EXPECT_EQ(CAPN_STRUCT, ptr.type);
EXPECT_EQ(8, ptr.datasz);
EXPECT_EQ(0, ptr.ptrsz);
EXPECT_EQ(0, ptr.ptrs);
EXPECT_EQ(UINT64_C(0xefcdab8967452301), capn_read64(ptr, 0));
EXPECT_EQ(UINT64_C(0), capn_read64(ptr, 8));
@ -75,7 +75,7 @@ static void setupStruct(struct capn *ctx) {
struct capn_ptr ptr = capn_new_struct(root.seg, 16, 6);
ASSERT_EQ(CAPN_STRUCT, ptr.type);
EXPECT_EQ(16, ptr.datasz);
EXPECT_EQ(48, ptr.ptrsz);
EXPECT_EQ(6, ptr.ptrs);
EXPECT_EQ(0, capn_setp(root, 0, ptr));
EXPECT_EQ(0, capn_write64(ptr, 0, UINT64_C(0x1011121314151617)));
@ -87,7 +87,7 @@ static void setupStruct(struct capn *ctx) {
capn_ptr subStruct = capn_new_struct(ptr.seg, 8, 0);
ASSERT_EQ(CAPN_STRUCT, subStruct.type);
EXPECT_EQ(8, subStruct.datasz);
EXPECT_EQ(0, subStruct.ptrsz);
EXPECT_EQ(0, subStruct.ptrs);
EXPECT_EQ(0, capn_write32(subStruct, 0, 123));
EXPECT_NE(0, capn_write32(subStruct, 8, 124));
EXPECT_EQ(0, capn_setp(ptr, 0, subStruct));
@ -108,19 +108,19 @@ static void setupStruct(struct capn *ctx) {
ASSERT_EQ(CAPN_COMPOSITE_LIST, list.type);
EXPECT_EQ(4, list.len);
EXPECT_EQ(8, list.datasz);
EXPECT_EQ(8, list.ptrsz);
EXPECT_EQ(1, list.ptrs);
EXPECT_EQ(0, capn_setp(ptr, 2, list));
for (int i = 0; i < 4; i++) {
capn_ptr element = capn_getp(list, i, 1);
ASSERT_EQ(CAPN_LIST_MEMBER, element.type);
EXPECT_EQ(8, element.datasz);
EXPECT_EQ(8, element.ptrsz);
EXPECT_EQ(1, element.ptrs);
EXPECT_EQ(0, capn_write32(element, 0, 300+i));
capn_ptr subelement = capn_new_struct(element.seg, 8, 0);
ASSERT_EQ(CAPN_STRUCT, subelement.type);
EXPECT_EQ(8, subelement.datasz);
EXPECT_EQ(0, subelement.ptrsz);
EXPECT_EQ(0, subelement.ptrs);
EXPECT_EQ(0, capn_write32(subelement, 0, 400+i));
EXPECT_EQ(0, capn_setp(element, 0, subelement));
}
@ -134,7 +134,7 @@ static void setupStruct(struct capn *ctx) {
ASSERT_EQ(CAPN_LIST, element.p.type);
EXPECT_EQ(i+1, element.p.len);
EXPECT_EQ(2, element.p.datasz);
EXPECT_EQ(0, element.p.ptrsz);
EXPECT_EQ(0, element.p.ptrs);
EXPECT_EQ(0, capn_setp(list, i, element.p));
for (int j = 0; j <= i; j++) {
EXPECT_EQ(0, capn_set16(element, j, 500+j));
@ -144,7 +144,7 @@ static void setupStruct(struct capn *ctx) {
capn_ptr recurse = capn_new_struct(ptr.seg, 0, 2);
EXPECT_EQ(CAPN_STRUCT, recurse.type);
EXPECT_EQ(0, recurse.datasz);
EXPECT_EQ(16, recurse.ptrsz);
EXPECT_EQ(2, recurse.ptrs);
EXPECT_EQ(0, capn_setp(recurse, 0, recurse));
EXPECT_EQ(0, capn_setp(ptr, 4, recurse));
@ -154,7 +154,7 @@ static void checkStruct(struct capn *ctx) {
capn_ptr ptr = capn_getp(capn_root(ctx), 0, 1);
EXPECT_EQ(CAPN_STRUCT, ptr.type);
EXPECT_EQ(16, ptr.datasz);
EXPECT_EQ(48, ptr.ptrsz);
EXPECT_EQ(6, ptr.ptrs);
EXPECT_EQ(UINT64_C(0x1011121314151617), capn_read64(ptr, 0));
EXPECT_EQ(UINT32_C(0x20212223), capn_read32(ptr, 8));
EXPECT_EQ(0x3031, capn_read16(ptr, 12));
@ -164,7 +164,7 @@ static void checkStruct(struct capn *ctx) {
capn_ptr subStruct = capn_getp(ptr, 0, 1);
EXPECT_EQ(CAPN_STRUCT, subStruct.type);
EXPECT_EQ(8, subStruct.datasz);
EXPECT_EQ(0, subStruct.ptrsz);
EXPECT_EQ(0, subStruct.ptrs);
EXPECT_EQ(123, capn_read32(subStruct, 0));
capn_list32 list32 = {capn_getp(ptr, 1, 1)};
@ -174,7 +174,7 @@ static void checkStruct(struct capn *ctx) {
EXPECT_EQ(CAPN_LIST, list32.p.type);
EXPECT_EQ(3, list32.p.len);
EXPECT_EQ(4, list32.p.datasz);
EXPECT_EQ(0, list32.p.ptrsz);
EXPECT_EQ(0, list32.p.ptrs);
EXPECT_EQ(200, capn_get32(list32, 0));
EXPECT_EQ(201, capn_get32(list32, 1));
EXPECT_EQ(202, capn_get32(list32, 2));
@ -187,19 +187,19 @@ static void checkStruct(struct capn *ctx) {
EXPECT_EQ(CAPN_COMPOSITE_LIST, list.type);
EXPECT_EQ(4, list.len);
EXPECT_EQ(8, list.datasz);
EXPECT_EQ(8, list.ptrsz);
EXPECT_EQ(1, list.ptrs);
for (int i = 0; i < 4; i++) {
capn_ptr element = capn_getp(list, i, 1);
EXPECT_EQ(CAPN_LIST_MEMBER, element.type);
EXPECT_EQ(8, element.datasz);
EXPECT_EQ(8, element.ptrsz);
EXPECT_EQ(1, element.ptrs);
EXPECT_EQ(300+i, capn_read32(element,0));
capn_ptr subelement = capn_getp(element, 0, 1);
EXPECT_EQ(CAPN_STRUCT, subelement.type);
EXPECT_EQ(8, subelement.datasz);
EXPECT_EQ(0, subelement.ptrsz);
EXPECT_EQ(0, subelement.ptrs);
EXPECT_EQ(400+i, capn_read32(subelement, 0));
}
@ -211,7 +211,7 @@ static void checkStruct(struct capn *ctx) {
EXPECT_EQ(CAPN_LIST, element.p.type);
EXPECT_EQ(i+1, element.p.len);
EXPECT_EQ(2, element.p.datasz);
EXPECT_EQ(0, element.p.ptrsz);
EXPECT_EQ(0, element.p.ptrs);
for (int j = 0; j <= i; j++) {
EXPECT_EQ(500+j, capn_get16(element, j));
}
@ -220,11 +220,11 @@ static void checkStruct(struct capn *ctx) {
capn_ptr recurse = capn_getp(ptr, 4, 1);
EXPECT_EQ(CAPN_STRUCT, recurse.type);
EXPECT_EQ(0, recurse.datasz);
EXPECT_EQ(16, recurse.ptrsz);
EXPECT_EQ(2, recurse.ptrs);
capn_ptr recurse_mbr = capn_getp(recurse, 0, 1);
EXPECT_EQ(CAPN_STRUCT, recurse_mbr.type);
EXPECT_EQ(0, recurse_mbr.datasz);
EXPECT_EQ(16, recurse_mbr.ptrsz);
EXPECT_EQ(2, recurse_mbr.ptrs);
EXPECT_EQ(recurse.seg, recurse_mbr.seg);
EXPECT_EQ(recurse.data, recurse_mbr.data);
EXPECT_EQ(CAPN_NULL, capn_getp(recurse, 1, 1).type);

76
capn.c
View file

@ -333,8 +333,8 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) {
struct_common:
ret.datasz = U32(U16(val >> 32)) * 8;
ret.ptrsz = U32(U16(val >> 48)) * 8;
e = d + ret.datasz + ret.ptrsz;
ret.ptrs = U32(U16(val >> 48));
e = d + ret.datasz + 8 * ret.ptrs;
break;
case LIST_PTR:
@ -381,11 +381,11 @@ static capn_ptr read_ptr(struct capn_segment *s, char *d) {
e = d + ret.len * 8;
ret.datasz = U32(U16(val >> 32)) * 8;
ret.ptrsz = U32(U16(val >> 48)) * 8;
ret.ptrs = U32(U16(val >> 48));
ret.len = U32(val) >> 2;
ret.type = CAPN_COMPOSITE_LIST;
if ((ret.datasz + ret.ptrsz) * ret.len != e - d) {
if ((ret.datasz + 8*ret.ptrs) * ret.len != e - d) {
goto err;
}
break;
@ -424,10 +424,10 @@ capn_ptr capn_getp(capn_ptr p, int off, int resolve) {
/* Return an inner pointer */
if (off < p.len) {
capn_ptr ret = {CAPN_LIST_MEMBER};
ret.data = p.data + off * (p.datasz + p.ptrsz);
ret.data = p.data + off * (p.datasz + 8*p.ptrs);
ret.seg = p.seg;
ret.datasz = p.datasz;
ret.ptrsz = p.ptrsz;
ret.ptrs = p.ptrs;
return ret;
} else {
goto err;
@ -435,18 +435,17 @@ capn_ptr capn_getp(capn_ptr p, int off, int resolve) {
case CAPN_LIST_MEMBER:
case CAPN_STRUCT:
off *= 8;
if (off >= p.ptrsz) {
if (off >= p.ptrs) {
goto err;
}
ret.data = p.data + p.datasz + off;
ret.data = p.data + p.datasz + 8*off;
break;
case CAPN_PTR_LIST:
if (off >= p.len) {
goto err;
}
ret.data = p.data + off * 8;
ret.data = p.data + 8*off;
break;
default:
@ -471,11 +470,11 @@ static int data_size(struct capn_ptr p) {
case CAPN_PTR_LIST:
return p.len*8;
case CAPN_STRUCT:
return p.datasz + p.ptrsz;
return p.datasz + 8*p.ptrs;
case CAPN_COMPOSITE_LIST:
return p.len * (p.datasz + p.ptrsz) + 8;
return p.len * (p.datasz + 8*p.ptrs) + 8;
case CAPN_LIST:
return p.len * (p.datasz + p.ptrsz);
return p.len * (p.datasz + 8*p.ptrs);
default:
return 0;
}
@ -486,11 +485,11 @@ static void write_ptr_tag(char *d, capn_ptr p, int off) {
switch (p.type) {
case CAPN_STRUCT:
val |= STRUCT_PTR | (U64(p.datasz/8) << 32) | (U64(p.ptrsz/8) << 48);
val |= STRUCT_PTR | (U64(p.datasz/8) << 32) | (U64(p.ptrs) << 48);
break;
case CAPN_COMPOSITE_LIST:
val |= LIST_PTR | (U64(COMPOSITE_LIST) << 32) | (U64(p.len * (p.datasz + p.ptrsz)/8) << 35);
val |= LIST_PTR | (U64(COMPOSITE_LIST) << 32) | (U64(p.len * (p.datasz/8 + p.ptrs)) << 35);
break;
case CAPN_LIST:
@ -602,14 +601,14 @@ static capn_ptr new_clone(struct capn_segment *s, capn_ptr p) {
switch (p.type) {
case CAPN_STRUCT:
case CAPN_LIST_MEMBER:
return capn_new_struct(s, p.datasz, p.ptrsz/8);
return capn_new_struct(s, p.datasz, p.ptrs);
case CAPN_PTR_LIST:
return capn_new_ptr_list(s, p.len);
case CAPN_BIT_LIST:
return capn_new_list1(s, p.len).p;
case CAPN_LIST:
case CAPN_COMPOSITE_LIST:
return capn_new_list(s, p.len, p.datasz, p.ptrsz/8);
return capn_new_list(s, p.len, p.datasz, p.ptrs);
default:
return p;
}
@ -620,7 +619,7 @@ static int is_ptr_equal(const struct capn_ptr *a, const struct capn_ptr *b) {
&& a->type == b->type
&& a->len == b->len
&& a->datasz == b->datasz
&& a->ptrsz == b->ptrsz;
&& a->ptrs == b->ptrs;
}
static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, struct capn_ptr *f, int *dep) {
@ -702,9 +701,9 @@ static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, st
t->data += t->datasz;
f->data += t->datasz;
}
if (t->ptrsz) {
if (t->ptrs) {
t->type = CAPN_PTR_LIST;
t->len = t->ptrsz/8;
t->len = t->ptrs;
(*dep)++;
}
return 0;
@ -717,13 +716,13 @@ static int copy_ptr(struct capn_segment *seg, char *data, struct capn_ptr *t, st
case CAPN_COMPOSITE_LIST:
if (!t->len) {
/* empty list - nothing to copy */
} else if (t->ptrsz && t->datasz) {
} else if (t->ptrs && t->datasz) {
(*dep)++;
} else if (t->datasz) {
memcpy(t->data, f->data, t->len * t->datasz);
} else if (t->ptrsz) {
} else if (t->ptrs) {
t->type = CAPN_PTR_LIST;
t->len *= t->ptrsz/8;
t->len *= t->ptrs;
(*dep)++;
}
return 0;
@ -748,13 +747,13 @@ static void copy_list_member(capn_ptr* t, capn_ptr *f, int *dep) {
f->data += f->datasz;
/* reset excess pointers */
sz = min(t->ptrsz, f->ptrsz);
memset(t->data + sz, 0, t->ptrsz - sz);
sz = min(t->ptrs, f->ptrs);
memset(t->data + sz, 0, 8*(t->ptrs - sz));
/* create a pointer list for the main loop to copy */
if (t->ptrsz) {
if (t->ptrs) {
t->type = CAPN_PTR_LIST;
t->len = t->ptrsz/8;
t->len = t->ptrs;
(*dep)++;
}
}
@ -785,7 +784,7 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) {
return -1;
to[0] = p;
to[0].data += off * (p.datasz + p.ptrsz);
to[0].data += off * (p.datasz + 8*p.ptrs);
from[0] = tgt;
copy_list_member(to, from, &dep);
break;
@ -793,15 +792,14 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) {
case CAPN_PTR_LIST:
if (off >= p.len)
return -1;
data = p.data + off * 8;
data = p.data + 8*off;
goto copy_ptr;
case CAPN_STRUCT:
case CAPN_LIST_MEMBER:
off *= 8;
if (off >= p.ptrsz)
if (off >= p.ptrs)
return -1;
data = p.data + p.datasz + off;
data = p.data + p.datasz + 8*off;
goto copy_ptr;
copy_ptr:
@ -845,8 +843,8 @@ int capn_setp(capn_ptr p, int off, capn_ptr tgt) {
copy_list_member(tn, fn, &dep);
fc->data += fc->datasz + fc->ptrsz;
tc->data += tc->datasz + tc->ptrsz;
fc->data += fc->datasz + 8*fc->ptrs;
tc->data += tc->datasz + 8*tc->ptrs;
tc->len--;
} else { /* CAPN_PTR_LIST */
@ -979,8 +977,8 @@ capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs) {
capn_ptr p = {CAPN_STRUCT};
p.seg = seg;
p.datasz = (datasz + 7) & ~7;
p.ptrsz = ptrs * 8;
new_object(&p, p.datasz + p.ptrsz);
p.ptrs = ptrs;
new_object(&p, p.datasz + 8*p.ptrs);
return p;
}
@ -994,8 +992,8 @@ capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs) {
} else if (ptrs || datasz > 8) {
p.type = CAPN_COMPOSITE_LIST;
p.datasz = (datasz + 7) & ~7;
p.ptrsz = ptrs*8;
new_object(&p, p.len * (p.datasz + p.ptrsz) + 8);
p.ptrs = ptrs;
new_object(&p, p.len * (p.datasz + 8*p.ptrs) + 8);
if (p.data) {
uint64_t hdr = STRUCT_PTR | (U64(p.len) << 2) | (U64(p.datasz/8) << 32) | (U64(ptrs) << 48);
*(uint64_t*) p.data = capn_flip64(hdr);
@ -1028,7 +1026,7 @@ capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz) {
capn_ptr p = {CAPN_PTR_LIST};
p.seg = seg;
p.len = sz;
p.ptrsz = 0;
p.ptrs = 0;
p.datasz = 0;
new_object(&p, sz*8);
return p;

2
capn.h
View file

@ -113,7 +113,7 @@ struct capn_ptr {
unsigned int type : 4;
unsigned int has_ptr_tag : 1;
unsigned int datasz : 19;
unsigned int ptrsz : 19;
unsigned int ptrs : 16;
int len;
char *data;
struct capn_segment *seg;

View file

@ -289,7 +289,7 @@ static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const
p.type,
p.has_ptr_tag,
p.datasz,
p.ptrsz,
p.ptrs,
p.len,
(int) (p.data-p.seg->data-8));