Skip to content

Commit

Permalink
Merge pull request etcd-io#2 from kite707/feat/majority-String_Slice_…
Browse files Browse the repository at this point in the history
…insertionSort

Feat/majority string slice insertion sort
  • Loading branch information
kite707 authored Feb 20, 2024
2 parents e22adc0 + a5b3dcd commit 45f1134
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 25 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.idea
*.a
*.o
47 changes: 30 additions & 17 deletions quorum/majority.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,33 @@ import (
"math"
"sort"
"strings"
"unsafe"
)

/*
#cgo LDFLAGS: -L./majorityC -lmajority
#include "majorityC/majority.h"
*/
import "C"

// MajorityConfig is a set of IDs that uses majority quorums to make decisions.
type MajorityConfig map[uint64]struct{}

// by chanjun
func (c MajorityConfig) String() string {
// make slice
sl := make([]uint64, 0, len(c))

// push key only
for id := range c {
sl = append(sl, id)
}
sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })
var buf strings.Builder
buf.WriteByte('(')
for i := range sl {
if i > 0 {
buf.WriteByte(' ')
}
fmt.Fprint(&buf, sl[i])

if len(sl) != 0 {
return C.GoString(C.cMajorityConfig((unsafe.Pointer(&sl[0])), C.int(len(sl))))
} else {
return "()"
}
buf.WriteByte(')')
return buf.String()
}

// Describe returns a (multi-line) representation of the commit indexes for the
Expand Down Expand Up @@ -102,22 +108,29 @@ func (c MajorityConfig) Describe(l AckedIndexer) string {
return buf.String()
}

// by chanjun
// Slice returns the MajorityConfig as a sorted slice.
func (c MajorityConfig) Slice() []uint64 {
var sl []uint64
for id := range c {
sl = append(sl, id)
}
sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })

// 조건문이 없으면 "index out of range [0] with length 0"라는 오류가 생김
// sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })
if len(sl) != 0 {
C.cSlice(unsafe.Pointer(&sl[0]), C.int(len(sl)))
}

return sl
}

func insertionSort(sl []uint64) {
a, b := 0, len(sl)
for i := a + 1; i < b; i++ {
for j := i; j > a && sl[j] < sl[j-1]; j-- {
sl[j], sl[j-1] = sl[j-1], sl[j]
}
// by chanjun
// insertionSort : just quick sort
func insertionSort(arr []uint64) {
if len(arr) != 0 {
// C 함수 호출
C.cinsertionSort(unsafe.Pointer(&arr[0]), C.int(len(arr)))
}
}

Expand Down
48 changes: 48 additions & 0 deletions quorum/majorityC/majority.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int compare(const void *a, const void *b){
return(*(long long unsigned int*)a - *(long long unsigned int*)b);
}

// sort slice by ascending & slice -> string
const char* cMajorityConfig(void* p, int size) {
long long unsigned int* sl = (long long unsigned int*) p;

qsort(sl, size, sizeof(long long unsigned int), compare);

char* buf = (char*)malloc((2 * size + 3) * sizeof(char));

int index = 0;
buf[index++] = '(';
for (int i = 0; i < size; i++) {
if (i > 0) {
buf[index++] = ' ';
}
index += sprintf(buf + index, "%llu", sl[i]);
}
buf[index++] = ')';
buf[index] = '\0';

return buf;
}

// sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] }) 의 역활
void cSlice(void* p, int size) {
// 형변환
long long unsigned int* arr = (long long unsigned int*)p;
qsort(arr, size, sizeof(long long unsigned int), compare);
}

void cinsertionSort(void* p, int size) {
long long unsigned int* sl = (long long unsigned int*) p;
int a = 0, b = size;
for (int i = a + 1; i < b; i++) {
for (int j = i; j > a && sl[j] < sl[j-1]; j--) {
long long unsigned int tmp = sl[j];
sl[j] = sl[j-1];
sl[j-1] = tmp;
}
}
}
19 changes: 19 additions & 0 deletions quorum/majorityC/majority.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//quorum.h
#ifndef _MAJORITY_H
#define _MAJORITY_H

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int compare(const void *a, const void *b);

// sort slice by ascending & slice -> string
const char* cMajorityConfig(void* p, int size);

// sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] }) 의 역활
void cSlice(void* p, int size);

void cinsertionSort(void* p, int size);

#endif
14 changes: 6 additions & 8 deletions quorum/quorum.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,17 @@

package quorum

import (
"math"
"strconv"
)
/*
#cgo LDFLAGS: -L./quorumC -lquorum
#include "quorumC/quorum.h"
*/
import "C"

// Index is a Raft log position.
type Index uint64

func (i Index) String() string {
if i == math.MaxUint64 {
return "∞"
}
return strconv.FormatUint(uint64(i), 10)
return C.GoString(C.index_to_string(C.uint64_t(i)))
}

// AckedIndexer allows looking up a commit index for a given ID of a voter
Expand Down
12 changes: 12 additions & 0 deletions quorum/quorum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _QUORUM_H
#define _QUORUM_H

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

typedef uint64_t Index;

const char *index_to_string(uint64_t i);

#endif
10 changes: 10 additions & 0 deletions quorum/quorumC/quorum.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "quorum.h"

const char *index_to_string(uint64_t i) {
static char buffer[21]; // buffer size for uint64_t
if (i == UINT64_MAX) {
return "∞";
}
snprintf(buffer, sizeof(buffer), "%" PRIu64, (uint64_t)i);
return buffer;
}
12 changes: 12 additions & 0 deletions quorum/quorumC/quorum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _QUORUM_H
#define _QUORUM_H

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

typedef uint64_t Index;

const char *index_to_string(uint64_t i);

#endif

0 comments on commit 45f1134

Please sign in to comment.