Skip to content

Commit

Permalink
ejson 0.9.10: acomplition of sort API
Browse files Browse the repository at this point in the history
  • Loading branch information
ziyht committed Apr 24, 2019
1 parent 4fe3591 commit 4352d72
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 80 deletions.
File renamed without changes.
File renamed without changes.
214 changes: 213 additions & 1 deletion src/libs/etools/ejson.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define _CRT_SECURE_NO_WARNINGS
#endif

#define EJSON_VERSION "ejson 0.9.9" // adjust some APIs
#define EJSON_VERSION "ejson 0.9.10" // acomplition of sort API

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -2159,6 +2159,218 @@ static __always_inline void __ejson_free_arr(_ejsr r)
}
}

/** -----------------------------------------------------
*
* ejson sort
*
* -----------------------------------------------------
*/

static _ejsn __merg_sort(_ejsn a, _ejsn b, uint len, eobj_cmp_cb cmp)
{
if(len == 2)
{
_n_lprev(a) = 0;
_n_lnext(b) = 0;

if(cmp(_n_o(a), _n_o(b)))
{
_n_lnext(a) = _n_lnext(b);
_n_lprev(b) = _n_lprev(a);
_n_lnext(b) = a;
_n_lprev(a) = b;

return b;
}
else
{
return a;
}
}
else if(len > 2)
{
_ejsn mid, midn; uint idx, midi;

_n_lprev(a) = 0;
_n_lnext(b) = 0;

midi = (len - 1) / 2; // split to [0, midi] (midi, len - 1]
mid = _n_lnext(a);
idx = 1;

while(idx != midi)
{
mid = _n_lnext(mid);
idx++;
}
idx++; // to count

//! do sort
midn = _n_lnext(mid);
a = __merg_sort(a , mid, idx, cmp);
b = __merg_sort(midn, b, len - idx, cmp);

//! do merge
{
_ejsn_t h; mid = &h;

_n_lnext(mid) = a;

do
{
while(_n_lnext(mid))
{
if(cmp(_n_o(_n_lnext(mid)), _n_o(b)))
{
_ejsn next = _n_lnext(b);

_n_lnext(b) = _n_lnext(mid);
_n_lprev(b) = _n_lprev(_n_lnext(mid));

_n_lprev(_n_lnext(mid)) = b;
_n_lnext(mid) = b;

b = next;

if(!b)
goto over;
}

mid = _n_lnext(mid);
}

if(cmp(_n_o(b), _n_o(mid)))
{
_n_lnext(mid) = b;
_n_lprev(b) = mid;

break;
}
else
{
_ejsn next = _n_lnext(b);

_n_lprev(b) = _n_lprev(mid);
_n_lnext(b) = mid;

_n_lnext(_n_lprev(b)) = b;
_n_lprev(mid) = b;

b = next;

if(!b)
goto over;
}
}while(1);
over:
return _n_lnext(&h);
}
}

_n_lprev(a) = 0;
_n_lnext(a) = 0;

return a;
}

static void __ejson_sort(_ejsr r, eobj_cmp_cb cmp)
{
int len = _r_len(r);

is1_ret(len <= 1, );

_r_head(r) = __merg_sort(_r_head(r), _r_tail(r), _r_len(r), cmp);
while(_n_lnext(_r_tail(r))) _r_tail(r) = _n_lnext(_r_tail(r));
}

eobj ejson_sort (eobj r, eobj_cmp_cb cmp) { if(r) __ejson_sort(_eo_rn(r), cmp); return r; }
eobj ejson_rsort(eobj r, constr rawk, eobj_cmp_cb cmp) { return ejson_sort(_getObjByRawk(_eo_rn(r), rawk), cmp); }
eobj ejson_ksort(eobj r, constr keys, eobj_cmp_cb cmp) { return ejson_sort(_getObjByKeys(_eo_rn(r), keys), cmp); }

int __KEYS_ACS(eobj a, eobj b)
{
cstr k_a, k_b; char c1, c2;

k_a = _eo_keyS(a);
k_b = _eo_keyS(b);

if(k_a)
{
if(k_b)
{
c1 = *k_a; c2 = *k_b;
while( c1 && c2 )
{
if(c1 > c2) return 1;
if(c1 < c2) return 0;

c1 = *(++k_a); c2 = *(++k_b);
}

return c1 > c2;
}
else
return 0;
}

return k_b ? 1 : 0;
}

int __KEYS_DES(eobj a, eobj b)
{
cstr k_a, k_b; char c1, c2;

k_a = _eo_keyS(a);
k_b = _eo_keyS(b);

if(k_a)
{
if(k_b)
{
c1 = *k_a; c2 = *k_b;
while( c1 && c2 )
{
if(c2 > c1) return 1;
if(c2 < c1) return 0;

c1 = *(++k_a); c2 = *(++k_b);
}

return c2 > c1;
}
else
return 0;
}

return k_b ? 1 : 0;
}

int __VALI_ACS(eobj a, eobj b)
{
if(_eo_typeo(a) == ENUM)
{
if(_eo_typeo(b) == ENUM)
return _eo_valI(a) - _eo_valI(b) > 0; // swap when return val > 0
else
return 0;
}

return _eo_typeo(b) == ENUM ? 1 : 0;
}

int __VALI_DES(eobj a, eobj b)
{
if(_eo_typeo(a) == ENUM)
{
if(_eo_typeo(b) == ENUM)
return _eo_valI(b) - _eo_valI(a) > 0;
else
return 0;
}

return _eo_typeo(b) == ENUM ? 1 : 0;
}

// --------------------------- dict definition -----------------------
#define DICT_HASH_FUNCTION_SEED 5381;
uint __MurmurHash2(const void *key, int len) {
Expand Down
47 changes: 19 additions & 28 deletions src/libs/etools/ejson.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,14 @@ int ejson_kcmpF(eobj r, constr keys, f64 val);
int ejson_kcmpS(eobj r, constr keys, constr str);

/** -----------------------------------------------------
* @brief
*
* ejson iterationg
*
* @note
* for perfomance, we do not check type of o in
* ejson_next() and ejson_prev()
*
* -----------------------------------------------------
*/
eobj ejson_first(eobj r);
eobj ejson_last (eobj r);
Expand Down Expand Up @@ -319,24 +319,6 @@ eobj ejson_setPk(eobj r, constr rawk, constr ptr);
eobj ejson_setRk(eobj r, constr rawk, uint len);


ejson ejso_setT(ejson obj, uint type); // only support FALSE/TRUE/NULL obj
ejson ejso_setF(ejson obj, double val); // only support NUM obj
ejson ejso_setS(ejson obj, constr val); // only support STR obj
void* ejso_setR(ejson obj, uint len); // only support RAW obj
ejson ejso_setP(ejson obj, void* ptr); // only support PTR obj

ejson ejsk_setT(ejson root, constr keys, uint type); // only support FALSE/TRUE/NULL obj
ejson ejsk_setF(ejson root, constr keys, double val); // only support NUM obj
ejson ejsk_setS(ejson root, constr keys, constr val); // only support STR obj
void* ejsk_setR(ejson root, constr keys, uint len); // only support RAW obj
ejson ejsk_setP(ejson root, constr keys, void* ptr); // only support PTR obj

ejson ejsr_setT(ejson root, constr rawk, uint type); // only support FALSE/TRUE/NULL obj
ejson ejsr_setF(ejson root, constr rawk, double val); // only support NUM obj
ejson ejsr_setS(ejson root, constr rawk, constr val); // only support STR obj
void* ejsr_setR(ejson root, constr rawk, uint len); // only support RAW obj
ejson ejsr_setP(ejson root, constr rawk, void* ptr); // only support PTR obj

/// -- ejson substitute string --
///
/// @return - ejson: [NULL] set failed
Expand All @@ -362,16 +344,25 @@ ejson ejsk_cntmm(ejson root, constr keys); // only support NUM obj
ejson ejsr_cntpp(ejson root, constr rawk); // only support NUM obj
ejson ejsr_cntmm(ejson root, constr rawk); // only support NUM obj

/// -- ejson sort --
typedef int (*__ecompar_fn) (ejson* _e1, ejson* _e2);
int __KEYS_ACS(ejson* _e1, ejson* _e2); // Ascending via key string in all obj, dictionary sequence
int __KEYS_DES(ejson* _e1, ejson* _e2); // Descending via key string in all obj, dictionary sequence
int __VALI_ACS(ejson* _e1, ejson* _e2); // Ascending via int value in NUM obj
int __VALI_DES(ejson* _e1, ejson* _e2); // Descending via int value in NUM obj
/** -----------------------------------------------
* @brief
* ejson sort operation
*
* @note:
* it only effect on EOBJ and EARR obj of ejson
*
*
*/

//! supplied default sort cb
int __KEYS_ACS(eobj a, eobj b); // Ascending via key string in all obj, dictionary sequence
int __KEYS_DES(eobj a, eobj b); // Descending via key string in all obj, dictionary sequence
int __VALI_ACS(eobj a, eobj b); // Ascending via int value in NUM obj
int __VALI_DES(eobj a, eobj b); // Descending via int value in NUM obj

ejson ejso_sort(ejson root, __ecompar_fn fn);
ejson ejsk_sort(ejson root, constr keys, __ecompar_fn fn);
ejson ejsr_sort(ejson root, constr rawk, __ecompar_fn fn);
eobj ejson_sort (eobj r, eobj_cmp_cb cmp);
eobj ejson_rsort(eobj r, constr rawk, eobj_cmp_cb cmp);
eobj ejson_ksort(eobj r, constr keys, eobj_cmp_cb cmp);

/// -- ejson version
constr ejson_version();
Expand Down
Loading

0 comments on commit 4352d72

Please sign in to comment.