diff --git a/.gitignore b/.gitignore index 485dee64..6e01b2f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .idea +*.a +*.o diff --git a/quorum/majority.go b/quorum/majority.go index 12766137..8915ee26 100644 --- a/quorum/majority.go +++ b/quorum/majority.go @@ -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 @@ -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))) } } diff --git a/quorum/majorityC/majority.c b/quorum/majorityC/majority.c new file mode 100644 index 00000000..113d8d94 --- /dev/null +++ b/quorum/majorityC/majority.c @@ -0,0 +1,48 @@ +#include +#include +#include + +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; + } + } +} \ No newline at end of file diff --git a/quorum/majorityC/majority.h b/quorum/majorityC/majority.h new file mode 100644 index 00000000..9abb6cbd --- /dev/null +++ b/quorum/majorityC/majority.h @@ -0,0 +1,19 @@ +//quorum.h +#ifndef _MAJORITY_H +#define _MAJORITY_H + +#include +#include +#include + +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 \ No newline at end of file diff --git a/quorum/quorum.go b/quorum/quorum.go index 2899e46c..dd51fd64 100644 --- a/quorum/quorum.go +++ b/quorum/quorum.go @@ -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 diff --git a/quorum/quorum.h b/quorum/quorum.h new file mode 100644 index 00000000..e5fdc610 --- /dev/null +++ b/quorum/quorum.h @@ -0,0 +1,12 @@ +#ifndef _QUORUM_H +#define _QUORUM_H + +#include +#include +#include + +typedef uint64_t Index; + +const char *index_to_string(uint64_t i); + +#endif \ No newline at end of file diff --git a/quorum/quorumC/quorum.c b/quorum/quorumC/quorum.c new file mode 100644 index 00000000..7544b995 --- /dev/null +++ b/quorum/quorumC/quorum.c @@ -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; +} \ No newline at end of file diff --git a/quorum/quorumC/quorum.h b/quorum/quorumC/quorum.h new file mode 100644 index 00000000..e5fdc610 --- /dev/null +++ b/quorum/quorumC/quorum.h @@ -0,0 +1,12 @@ +#ifndef _QUORUM_H +#define _QUORUM_H + +#include +#include +#include + +typedef uint64_t Index; + +const char *index_to_string(uint64_t i); + +#endif \ No newline at end of file