Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make compaction available for Oj::Doc #650

Merged
merged 4 commits into from Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .clang-format
@@ -0,0 +1,7 @@
BasedOnStyle: Mozilla
IndentWidth: 4
BreakBeforeBraces: Attach
ColumnLimit: 0
AlwaysBreakAfterReturnType: AllDefinitions
DerivePointerAlignment: false
PointerAlignment: Right
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# CHANGELOG

## Ongoing

- Added support for `GC.compact` on `Oj::Doc`

## 3.11.3 - 2021-03-09

- Fixed `respond_to?` method on `Oj::EasyHash`.
Expand Down
1 change: 0 additions & 1 deletion Rakefile
Expand Up @@ -92,4 +92,3 @@ begin

rescue LoadError
end

54 changes: 27 additions & 27 deletions ext/oj/buf.h
Expand Up @@ -6,11 +6,11 @@
#include "ruby.h"

typedef struct _buf {
char *head;
char *end;
char *tail;
char base[1024];
} *Buf;
char *head;
char *end;
char *tail;
char base[1024];
} * Buf;

inline static void
buf_init(Buf buf) {
Expand All @@ -34,18 +34,18 @@ buf_len(Buf buf) {
inline static void
buf_append_string(Buf buf, const char *s, size_t slen) {
if (buf->end <= buf->tail + slen) {
size_t len = buf->end - buf->head;
size_t toff = buf->tail - buf->head;
size_t new_len = len + slen + len / 2;
size_t len = buf->end - buf->head;
size_t toff = buf->tail - buf->head;
size_t new_len = len + slen + len / 2;

if (buf->base == buf->head) {
buf->head = ALLOC_N(char, new_len);
memcpy(buf->head, buf->base, len);
} else {
REALLOC_N(buf->head, char, new_len);
}
buf->tail = buf->head + toff;
buf->end = buf->head + new_len - 1;
if (buf->base == buf->head) {
buf->head = ALLOC_N(char, new_len);
memcpy(buf->head, buf->base, len);
} else {
REALLOC_N(buf->head, char, new_len);
}
buf->tail = buf->head + toff;
buf->end = buf->head + new_len - 1;
}
memcpy(buf->tail, s, slen);
buf->tail += slen;
Expand All @@ -54,18 +54,18 @@ buf_append_string(Buf buf, const char *s, size_t slen) {
inline static void
buf_append(Buf buf, char c) {
if (buf->end <= buf->tail) {
size_t len = buf->end - buf->head;
size_t toff = buf->tail - buf->head;
size_t new_len = len + len / 2;
size_t len = buf->end - buf->head;
size_t toff = buf->tail - buf->head;
size_t new_len = len + len / 2;

if (buf->base == buf->head) {
buf->head = ALLOC_N(char, new_len);
memcpy(buf->head, buf->base, len);
} else {
REALLOC_N(buf->head, char, new_len);
}
buf->tail = buf->head + toff;
buf->end = buf->head + new_len - 1;
if (buf->base == buf->head) {
buf->head = ALLOC_N(char, new_len);
memcpy(buf->head, buf->base, len);
} else {
REALLOC_N(buf->head, char, new_len);
}
buf->tail = buf->head + toff;
buf->end = buf->head + new_len - 1;
}
*buf->tail = c;
buf->tail++;
Expand Down
92 changes: 46 additions & 46 deletions ext/oj/cache8.c
@@ -1,40 +1,40 @@
// Copyright (c) 2011 Peter Ohler. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for license details.

#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "ruby.h"
#include "cache8.h"
#include "ruby.h"

#define BITS 4
#define MASK 0x000000000000000FULL
#define SLOT_CNT 16
#define DEPTH 16
#define BITS 4
#define MASK 0x000000000000000FULL
#define SLOT_CNT 16
#define DEPTH 16

typedef union {
struct _cache8 *child;
slot_t value;
struct _cache8 *child;
slot_t value;
} Bucket;

struct _cache8 {
Bucket buckets[SLOT_CNT];
Bucket buckets[SLOT_CNT];
};

static void cache8_delete(Cache8 cache, int depth);
static void slot_print(Cache8 cache, sid_t key, unsigned int depth);
static void cache8_delete(Cache8 cache, int depth);
static void slot_print(Cache8 cache, sid_t key, unsigned int depth);

void
oj_cache8_new(Cache8 *cache) {
Bucket *b;
int i;
Bucket *b;
int i;

*cache = ALLOC(struct _cache8);
for (i = SLOT_CNT, b = (*cache)->buckets; 0 < i; i--, b++) {
b->value = 0;
b->value = 0;
}
}

Expand All @@ -45,33 +45,33 @@ oj_cache8_delete(Cache8 cache) {

static void
cache8_delete(Cache8 cache, int depth) {
Bucket *b;
unsigned int i;
Bucket *b;
unsigned int i;

for (i = 0, b = cache->buckets; i < SLOT_CNT; i++, b++) {
if (0 != b->child) {
if (DEPTH - 1 != depth) {
cache8_delete(b->child, depth + 1);
}
}
if (0 != b->child) {
if (DEPTH - 1 != depth) {
cache8_delete(b->child, depth + 1);
}
}
}
xfree(cache);
}

slot_t
oj_cache8_get(Cache8 cache, sid_t key, slot_t **slot) {
Bucket *b;
int i;
sid_t k8 = (sid_t)key;
sid_t k;
Bucket *b;
int i;
sid_t k8 = (sid_t)key;
sid_t k;

for (i = 64 - BITS; 0 < i; i -= BITS) {
k = (k8 >> i) & MASK;
b = cache->buckets + k;
if (0 == b->child) {
oj_cache8_new(&b->child);
}
cache = b->child;
k = (k8 >> i) & MASK;
b = cache->buckets + k;
if (0 == b->child) {
oj_cache8_new(&b->child);
}
cache = b->child;
}
*slot = &(cache->buckets + (k8 & MASK))->value;

Expand All @@ -86,24 +86,24 @@ oj_cache8_print(Cache8 cache) {

static void
slot_print(Cache8 c, sid_t key, unsigned int depth) {
Bucket *b;
unsigned int i;
sid_t k8 = (sid_t)key;
sid_t k;
Bucket *b;
unsigned int i;
sid_t k8 = (sid_t)key;
sid_t k;

for (i = 0, b = c->buckets; i < SLOT_CNT; i++, b++) {
if (0 != b->child) {
k = (k8 << BITS) | i;
/*printf("*** key: 0x%016llx depth: %u i: %u\n", k, depth, i); */
if (DEPTH - 1 == depth) {
if (0 != b->child) {
k = (k8 << BITS) | i;
/*printf("*** key: 0x%016llx depth: %u i: %u\n", k, depth, i); */
if (DEPTH - 1 == depth) {
#if IS_WINDOWS
printf("0x%016lx: %4lu\n", (long unsigned int)k, (long unsigned int)b->value);
printf("0x%016lx: %4lu\n", (long unsigned int)k, (long unsigned int)b->value);
#else
printf("0x%016llx: %4llu\n", (long long unsigned int)k, (long long unsigned int)b->value);
printf("0x%016llx: %4llu\n", (long long unsigned int)k, (long long unsigned int)b->value);
#endif
} else {
slot_print(b->child, k, depth + 1);
}
}
} else {
slot_print(b->child, k, depth + 1);
}
}
}
}
14 changes: 7 additions & 7 deletions ext/oj/cache8.h
Expand Up @@ -7,15 +7,15 @@
#include "ruby.h"
#include "stdint.h"

typedef struct _cache8 *Cache8;
typedef uint64_t slot_t;
typedef uint64_t sid_t;
typedef struct _cache8 *Cache8;
typedef uint64_t slot_t;
typedef uint64_t sid_t;

extern void oj_cache8_new(Cache8 *cache);
extern void oj_cache8_delete(Cache8 cache);
extern void oj_cache8_new(Cache8 *cache);
extern void oj_cache8_delete(Cache8 cache);

extern slot_t oj_cache8_get(Cache8 cache, sid_t key, slot_t **slot);
extern slot_t oj_cache8_get(Cache8 cache, sid_t key, slot_t **slot);

extern void oj_cache8_print(Cache8 cache);
extern void oj_cache8_print(Cache8 cache);

#endif /* OJ_CACHE8_H */
52 changes: 26 additions & 26 deletions ext/oj/circarray.c
Expand Up @@ -5,10 +5,10 @@

CircArray
oj_circ_array_new() {
CircArray ca;
CircArray ca;

if (0 == (ca = ALLOC(struct _circArray))) {
rb_raise(rb_eNoMemError, "not enough memory\n");
rb_raise(rb_eNoMemError, "not enough memory\n");
}
ca->objs = ca->obj_array;
ca->size = sizeof(ca->obj_array) / sizeof(VALUE);
Expand All @@ -20,46 +20,46 @@ oj_circ_array_new() {
void
oj_circ_array_free(CircArray ca) {
if (ca->objs != ca->obj_array) {
xfree(ca->objs);
xfree(ca->objs);
}
xfree(ca);
}

void
oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id) {
if (0 < id && 0 != ca) {
unsigned long i;
unsigned long i;

if (ca->size < id) {
unsigned long cnt = id + 512;
if (ca->size < id) {
unsigned long cnt = id + 512;

if (ca->objs == ca->obj_array) {
if (0 == (ca->objs = ALLOC_N(VALUE, cnt))) {
rb_raise(rb_eNoMemError, "not enough memory\n");
}
memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
} else {
REALLOC_N(ca->objs, VALUE, cnt);
}
ca->size = cnt;
}
id--;
for (i = ca->cnt; i < id; i++) {
ca->objs[i] = Qnil;
}
ca->objs[id] = obj;
if (ca->cnt <= id) {
ca->cnt = id + 1;
}
if (ca->objs == ca->obj_array) {
if (0 == (ca->objs = ALLOC_N(VALUE, cnt))) {
rb_raise(rb_eNoMemError, "not enough memory\n");
}
memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt);
} else {
REALLOC_N(ca->objs, VALUE, cnt);
}
ca->size = cnt;
}
id--;
for (i = ca->cnt; i < id; i++) {
ca->objs[i] = Qnil;
}
ca->objs[id] = obj;
if (ca->cnt <= id) {
ca->cnt = id + 1;
}
}
}

VALUE
oj_circ_array_get(CircArray ca, unsigned long id) {
VALUE obj = Qnil;
VALUE obj = Qnil;

if (id <= ca->cnt && 0 != ca) {
obj = ca->objs[id - 1];
obj = ca->objs[id - 1];
}
return obj;
}
18 changes: 9 additions & 9 deletions ext/oj/circarray.h
Expand Up @@ -7,15 +7,15 @@
#include "ruby.h"

typedef struct _circArray {
VALUE obj_array[1024];
VALUE *objs;
unsigned long size; // allocated size or initial array size
unsigned long cnt;
} *CircArray;
VALUE obj_array[1024];
VALUE *objs;
unsigned long size; // allocated size or initial array size
unsigned long cnt;
} * CircArray;

extern CircArray oj_circ_array_new(void);
extern void oj_circ_array_free(CircArray ca);
extern void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id);
extern VALUE oj_circ_array_get(CircArray ca, unsigned long id);
extern CircArray oj_circ_array_new(void);
extern void oj_circ_array_free(CircArray ca);
extern void oj_circ_array_set(CircArray ca, VALUE obj, unsigned long id);
extern VALUE oj_circ_array_get(CircArray ca, unsigned long id);

#endif /* OJ_CIRCARRAY_H */