From a171c611d3691e4825eb4212e6196fb2af3459a1 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 23 Mar 2021 22:35:04 +0530 Subject: [PATCH 01/14] added fix for normalize --- query/outputnode.go | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index f0c2c36f56f..4b547e7ce8e 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -812,11 +812,44 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) if paCopy == nil { paCopy = caCopy } else { - temp := paCopy + tempPa := paCopy + var leftStartPtr fastJsonNode + var leftEndPtr fastJsonNode + for caCopy != nil { + var exist bool + nn := enc.copySingleNode(caCopy) + for paCopy != nil { + if enc.getAttr(paCopy) == enc.getAttr(caCopy) { + temp := paCopy.next + nn.next = temp + paCopy.next = nn + exist = true + break + } else { + paCopy = paCopy.next + } + } + if !exist { + if leftStartPtr == nil { + leftStartPtr = nn + leftEndPtr = nn + + } else { + leftEndPtr.next = nn + leftEndPtr = nn + } + } + caCopy = caCopy.next + paCopy = tempPa + } + temp := tempPa for temp.next != nil { temp = temp.next } - temp.next = caCopy + temp.next = leftStartPtr + paCopy = tempPa + // iterate over nodes of ca + // if it's inside p then add it next to it } mergedList = append(mergedList, paCopy) } @@ -893,6 +926,11 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { for _, slice := range parentSlice { // From every slice we need to remove node with attribute "uid". + slice1 := slice + for slice1 != nil { + glog.Infof("%v", enc.getAttr(slice1)) + slice1 = slice1.next + } var prev, cur fastJsonNode cur = slice for cur != nil { From 3803753ce1036c9c8fe25fa71329b06e0de6fa52 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 23 Mar 2021 22:35:04 +0530 Subject: [PATCH 02/14] removed log statements --- query/outputnode.go | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index f0c2c36f56f..8cda8f550ea 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -812,11 +812,44 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) if paCopy == nil { paCopy = caCopy } else { - temp := paCopy + tempPa := paCopy + var leftStartPtr fastJsonNode + var leftEndPtr fastJsonNode + for caCopy != nil { + var exist bool + nn := enc.copySingleNode(caCopy) + for paCopy != nil { + if enc.getAttr(paCopy) == enc.getAttr(caCopy) { + temp := paCopy.next + nn.next = temp + paCopy.next = nn + exist = true + break + } else { + paCopy = paCopy.next + } + } + if !exist { + if leftStartPtr == nil { + leftStartPtr = nn + leftEndPtr = nn + + } else { + leftEndPtr.next = nn + leftEndPtr = nn + } + } + caCopy = caCopy.next + paCopy = tempPa + } + temp := tempPa for temp.next != nil { temp = temp.next } - temp.next = caCopy + temp.next = leftStartPtr + paCopy = tempPa + // iterate over nodes of ca + // if it's inside p then add it next to it } mergedList = append(mergedList, paCopy) } From 03f69ae0c6d4dcbb01fe3cc4925bb3387d6d84e8 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 23 Mar 2021 22:44:00 +0530 Subject: [PATCH 03/14] removed log statements --- query/outputnode.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 4b547e7ce8e..8cda8f550ea 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -926,11 +926,6 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { for _, slice := range parentSlice { // From every slice we need to remove node with attribute "uid". - slice1 := slice - for slice1 != nil { - glog.Infof("%v", enc.getAttr(slice1)) - slice1 = slice1.next - } var prev, cur fastJsonNode cur = slice for cur != nil { From c5e47441b9902347cc5ad98a153736d9bb8e42a0 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Wed, 24 Mar 2021 12:43:48 +0530 Subject: [PATCH 04/14] clean code and added test --- query/outputnode.go | 31 +++++++++++---------- query/query2_test.go | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 8cda8f550ea..1726fb2f6ab 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -812,17 +812,21 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) if paCopy == nil { paCopy = caCopy } else { + // This code merge child and parent lists such that nodes with same attribute id's comes together in merged list tempPa := paCopy - var leftStartPtr fastJsonNode - var leftEndPtr fastJsonNode + // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start and end pointer of child list nodes whose attribute id's + // doesn't match with attribute id's of some nodes in parent list + var unmatchedNodesStartPtr fastJsonNode + var unmatchedNodesEndPtr fastJsonNode for caCopy != nil { var exist bool - nn := enc.copySingleNode(caCopy) + caCopyNext := caCopy.next for paCopy != nil { + // Merge child nodes in parent list whose attribute id's matched with attribute id's of some nodes in parent list if enc.getAttr(paCopy) == enc.getAttr(caCopy) { temp := paCopy.next - nn.next = temp - paCopy.next = nn + caCopy.next = temp + paCopy.next = caCopy exist = true break } else { @@ -830,26 +834,25 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) } } if !exist { - if leftStartPtr == nil { - leftStartPtr = nn - leftEndPtr = nn + if unmatchedNodesStartPtr == nil { + unmatchedNodesStartPtr = caCopy + unmatchedNodesEndPtr = caCopy } else { - leftEndPtr.next = nn - leftEndPtr = nn + unmatchedNodesEndPtr.next = caCopy + unmatchedNodesEndPtr = caCopy } } - caCopy = caCopy.next + caCopy = caCopyNext paCopy = tempPa } + // Merge all unmatched nodes at the end of parent List temp := tempPa for temp.next != nil { temp = temp.next } - temp.next = leftStartPtr + temp.next = unmatchedNodesStartPtr paCopy = tempPa - // iterate over nodes of ca - // if it's inside p then add it next to it } mergedList = append(mergedList, paCopy) } diff --git a/query/query2_test.go b/query/query2_test.go index 787afcc9440..e3e568bae30 100644 --- a/query/query2_test.go +++ b/query/query2_test.go @@ -1841,6 +1841,70 @@ func TestNormalizeDirective(t *testing.T) { }`, js) } +func TestNormalizeDirectiveWithRecurseDirective(t *testing.T) { + query := ` + { + me(func: uid(0x01)) @recurse @normalize { + n: name + d: dob + friend + } + }` + + js := processQueryNoErr(t, query) + require.JSONEq(t, ` + { + "data": { + "me": [ + { + "n": [ + "Michonne", + "Michonne", + "Rick Grimes" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1910-01-01T00:00:00Z", + "1910-01-02T00:00:00Z" + ] + }, + { + "n": [ + "Michonne", + "Glenn Rhee" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1909-05-05T00:00:00Z" + ] + }, + { + "n": [ + "Michonne", + "Daryl Dixon" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1909-01-10T00:00:00Z" + ] + }, + { + "n": [ + "Michonne", + "Glenn Rhee", + "Andrea" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1909-05-05T00:00:00Z", + "1901-01-15T00:00:00Z" + ] + } + ] + } + }`, js) +} + func TestNormalizeDirectiveSubQueryLevel1(t *testing.T) { query := ` { From d7c121cc15f93622362d3dc1d509ad747e865806 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Wed, 24 Mar 2021 12:47:58 +0530 Subject: [PATCH 05/14] clean comments --- query/outputnode.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 1726fb2f6ab..8ef566f70a3 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -812,17 +812,19 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) if paCopy == nil { paCopy = caCopy } else { - // This code merge child and parent lists such that nodes with same attribute id's comes together in merged list + // This code merge child and parent lists such that nodes with same attribute id's + // comes together in merged list tempPa := paCopy - // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start and end pointer of child list nodes whose attribute id's - // doesn't match with attribute id's of some nodes in parent list + // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start and end pointer of whose attribute + // id's doesn't match with attribute id's of some nodes in parent list var unmatchedNodesStartPtr fastJsonNode var unmatchedNodesEndPtr fastJsonNode for caCopy != nil { var exist bool caCopyNext := caCopy.next for paCopy != nil { - // Merge child nodes in parent list whose attribute id's matched with attribute id's of some nodes in parent list + // Merge child nodes in parent list whose attribute id's matched with attribute id's of + // some nodes in parent list if enc.getAttr(paCopy) == enc.getAttr(caCopy) { temp := paCopy.next caCopy.next = temp From 00ddbd01867cf07517c7a97d1e1bd76f4c00fe3f Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Wed, 24 Mar 2021 12:52:39 +0530 Subject: [PATCH 06/14] clean comments --- query/outputnode.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 8ef566f70a3..315aea97227 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -812,19 +812,20 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) if paCopy == nil { paCopy = caCopy } else { - // This code merge child and parent lists such that nodes with same attribute id's - // comes together in merged list + // This code merge child and parent lists such that nodes with + // same attribute id's comes together in merged list tempPa := paCopy - // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start and end pointer of whose attribute - // id's doesn't match with attribute id's of some nodes in parent list + // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start + // and end pointer of whose attribute id's doesn't match with + // attribute id's of some nodes in parent list var unmatchedNodesStartPtr fastJsonNode var unmatchedNodesEndPtr fastJsonNode for caCopy != nil { var exist bool caCopyNext := caCopy.next for paCopy != nil { - // Merge child nodes in parent list whose attribute id's matched with attribute id's of - // some nodes in parent list + // Merge child nodes in parent list whose attribute id's matched + // with attribute id's of some nodes in parent list if enc.getAttr(paCopy) == enc.getAttr(caCopy) { temp := paCopy.next caCopy.next = temp From 9ba4eb7b41f5d1815cb25a0e1e0a0588545bd23e Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Thu, 25 Mar 2021 23:25:46 +0530 Subject: [PATCH 07/14] refactor code --- query/outputnode.go | 56 +++++++++++++------------ query/query2_test.go | 98 ++++++++++++++++++++++---------------------- 2 files changed, 79 insertions(+), 75 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 315aea97227..ab2798073bb 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -814,50 +814,54 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) } else { // This code merge child and parent lists such that nodes with // same attribute id's comes together in merged list - tempPa := paCopy + startCaPtr := caCopy // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start - // and end pointer of whose attribute id's doesn't match with - // attribute id's of some nodes in parent list + // and end pointer of parent list nodes whose attribute id's doesn't match with + // attribute id's of any node in child list var unmatchedNodesStartPtr fastJsonNode var unmatchedNodesEndPtr fastJsonNode - for caCopy != nil { + for paCopy != nil { var exist bool - caCopyNext := caCopy.next - for paCopy != nil { - // Merge child nodes in parent list whose attribute id's matched - // with attribute id's of some nodes in parent list + var caCopyPrev fastJsonNode + paCopyNext := paCopy.next + for caCopy != nil { + // Merge parent node in child list, if attribute id of it match + // with attribute id of any node in child list if enc.getAttr(paCopy) == enc.getAttr(caCopy) { - temp := paCopy.next - caCopy.next = temp - paCopy.next = caCopy + if caCopyPrev == nil { + paCopy.next = startCaPtr + startCaPtr = paCopy + } else { + caCopyPrev.next = paCopy + paCopy.next = caCopy + } exist = true break - } else { - paCopy = paCopy.next } + caCopyPrev = caCopy + caCopy = caCopy.next } if !exist { if unmatchedNodesStartPtr == nil { - unmatchedNodesStartPtr = caCopy - unmatchedNodesEndPtr = caCopy + unmatchedNodesStartPtr = paCopy + unmatchedNodesEndPtr = paCopy } else { - unmatchedNodesEndPtr.next = caCopy - unmatchedNodesEndPtr = caCopy + unmatchedNodesEndPtr.next = paCopy + unmatchedNodesEndPtr = paCopy } } - caCopy = caCopyNext - paCopy = tempPa + caCopy = startCaPtr + paCopy = paCopyNext } - // Merge all unmatched nodes at the end of parent List - temp := tempPa - for temp.next != nil { - temp = temp.next + // Merge all unmatched nodes at the beginning of child List + if unmatchedNodesStartPtr != nil { + unmatchedNodesEndPtr.next = startCaPtr + startCaPtr = unmatchedNodesStartPtr } - temp.next = unmatchedNodesStartPtr - paCopy = tempPa + caCopy = startCaPtr } - mergedList = append(mergedList, paCopy) + mergedList = append(mergedList, caCopy) } } return mergedList, nil diff --git a/query/query2_test.go b/query/query2_test.go index e3e568bae30..74e98b0d75a 100644 --- a/query/query2_test.go +++ b/query/query2_test.go @@ -1854,55 +1854,55 @@ func TestNormalizeDirectiveWithRecurseDirective(t *testing.T) { js := processQueryNoErr(t, query) require.JSONEq(t, ` { - "data": { - "me": [ - { - "n": [ - "Michonne", - "Michonne", - "Rick Grimes" - ], - "d": [ - "1910-01-01T00:00:00Z", - "1910-01-01T00:00:00Z", - "1910-01-02T00:00:00Z" - ] - }, - { - "n": [ - "Michonne", - "Glenn Rhee" - ], - "d": [ - "1910-01-01T00:00:00Z", - "1909-05-05T00:00:00Z" - ] - }, - { - "n": [ - "Michonne", - "Daryl Dixon" - ], - "d": [ - "1910-01-01T00:00:00Z", - "1909-01-10T00:00:00Z" - ] - }, - { - "n": [ - "Michonne", - "Glenn Rhee", - "Andrea" - ], - "d": [ - "1910-01-01T00:00:00Z", - "1909-05-05T00:00:00Z", - "1901-01-15T00:00:00Z" - ] - } - ] - } - }`, js) + "data": { + "me": [ + { + "n": [ + "Michonne", + "Rick Grimes", + "Michonne" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1910-01-02T00:00:00Z", + "1910-01-01T00:00:00Z" + ] + }, + { + "n": [ + "Michonne", + "Glenn Rhee" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1909-05-05T00:00:00Z" + ] + }, + { + "n": [ + "Michonne", + "Daryl Dixon" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1909-01-10T00:00:00Z" + ] + }, + { + "n": [ + "Michonne", + "Andrea", + "Glenn Rhee" + ], + "d": [ + "1910-01-01T00:00:00Z", + "1901-01-15T00:00:00Z", + "1909-05-05T00:00:00Z" + ] + } + ] + } + }`, js) } func TestNormalizeDirectiveSubQueryLevel1(t *testing.T) { From 68314a0b3293f64ee5dd539d74a3b63036c42027 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Mon, 29 Mar 2021 16:00:47 +0530 Subject: [PATCH 08/14] added merge sort for fastJson node --- query/outputnode.go | 121 ++++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 48 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index ab2798073bb..90e069e8aa0 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -812,56 +812,13 @@ func (enc *encoder) merge(parent, child []fastJsonNode) ([]fastJsonNode, error) if paCopy == nil { paCopy = caCopy } else { - // This code merge child and parent lists such that nodes with - // same attribute id's comes together in merged list - startCaPtr := caCopy - // unmatchedNodesStartPtr and unmatchedNodesEndPtr stores start - // and end pointer of parent list nodes whose attribute id's doesn't match with - // attribute id's of any node in child list - var unmatchedNodesStartPtr fastJsonNode - var unmatchedNodesEndPtr fastJsonNode - for paCopy != nil { - var exist bool - var caCopyPrev fastJsonNode - paCopyNext := paCopy.next - for caCopy != nil { - // Merge parent node in child list, if attribute id of it match - // with attribute id of any node in child list - if enc.getAttr(paCopy) == enc.getAttr(caCopy) { - if caCopyPrev == nil { - paCopy.next = startCaPtr - startCaPtr = paCopy - } else { - caCopyPrev.next = paCopy - paCopy.next = caCopy - } - exist = true - break - } - caCopyPrev = caCopy - caCopy = caCopy.next - } - if !exist { - if unmatchedNodesStartPtr == nil { - unmatchedNodesStartPtr = paCopy - unmatchedNodesEndPtr = paCopy - - } else { - unmatchedNodesEndPtr.next = paCopy - unmatchedNodesEndPtr = paCopy - } - } - caCopy = startCaPtr - paCopy = paCopyNext + temp := paCopy + for temp.next != nil { + temp = temp.next } - // Merge all unmatched nodes at the beginning of child List - if unmatchedNodesStartPtr != nil { - unmatchedNodesEndPtr.next = startCaPtr - startCaPtr = unmatchedNodesStartPtr - } - caCopy = startCaPtr + temp.next = caCopy } - mergedList = append(mergedList, caCopy) + mergedList = append(mergedList, paCopy) } } return mergedList, nil @@ -936,6 +893,7 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { for _, slice := range parentSlice { // From every slice we need to remove node with attribute "uid". + MergeSort(&slice, enc) var prev, cur fastJsonNode cur = slice for cur != nil { @@ -959,6 +917,73 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { return parentSlice, nil } +func MergeSort(headRef *fastJsonNode, enc *encoder) { + head := *headRef + var a fastJsonNode + var b fastJsonNode + + /* Base case -- length 0 or 1 */ + if headRef == nil || (*headRef).next == nil { + return + } + + /* Split head into 'a' and 'b' sublists */ + FrontBackSplit(head, &a, &b) + + /* Recursively sort the sublists */ + MergeSort(&a, enc) + MergeSort(&b, enc) + + /* answer = merge the two sorted lists together */ + *headRef = SortedMerge(a, b, enc) +} + +func SortedMerge(a fastJsonNode, b fastJsonNode, enc *encoder) fastJsonNode { + var result fastJsonNode + + /* Base cases */ + if a == nil { + return b + } else if b == nil { + return a + } + + /* Pick either a or b, and recur */ + if Less(enc, a, b) { + result = a + result.next = SortedMerge(a.next, b, enc) + } else { + result = b + result.next = SortedMerge(a, b.next, enc) + } + return result +} + +func Less(enc *encoder, i fastJsonNode, j fastJsonNode) bool { + attri := enc.getAttr(i) + attrj := enc.getAttr(j) + cmp := strings.Compare(enc.attrForID(attri), enc.attrForID(attrj)) + return cmp < 0 +} + +func FrontBackSplit(source fastJsonNode, + frontRef *fastJsonNode, backRef *fastJsonNode) { + slow := source + fast := source.next + + for fast != nil { + fast = fast.next + if fast != nil { + slow = slow.next + fast = fast.next + } + } + + *frontRef = source + *backRef = slow.next + slow.next = nil +} + func (sg *SubGraph) addGroupby(enc *encoder, fj fastJsonNode, res *groupResults, fname string) error { From ad64ee6430e6e40b41cc50f11caf359a4911ec4d Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 30 Mar 2021 17:41:15 +0530 Subject: [PATCH 09/14] fixed a bug --- query/outputnode.go | 135 ++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 90e069e8aa0..cfd9312ccdb 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -150,6 +150,68 @@ func newEncoder() *encoder { return e } +// Sort the given fastJson list +func (enc *encoder) MergeSort(headRef *fastJsonNode) { + head := *headRef + var a fastJsonNode + var b fastJsonNode + + if headRef == nil || (*headRef).next == nil { + return + } + + FrontBackSplit(head, &a, &b) + + enc.MergeSort(&a) + enc.MergeSort(&b) + + *headRef = enc.SortedMerge(a, b) +} + +func (enc *encoder) SortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode { + var result fastJsonNode + + if a == nil { + return b + } else if b == nil { + return a + } + + if enc.Less(a, b) { + result = a + result.next = enc.SortedMerge(a.next, b) + } else { + result = b + result.next = enc.SortedMerge(a, b.next) + } + return result +} + +func (enc *encoder) Less(i fastJsonNode, j fastJsonNode) bool { + attri := enc.getAttr(i) + attrj := enc.getAttr(j) + cmp := strings.Compare(enc.attrForID(attri), enc.attrForID(attrj)) + return cmp <= 0 +} + +func FrontBackSplit(source fastJsonNode, + frontRef *fastJsonNode, backRef *fastJsonNode) { + slow := source + fast := source.next + + for fast != nil { + fast = fast.next + if fast != nil { + slow = slow.next + fast = fast.next + } + } + + *frontRef = source + *backRef = slow.next + slow.next = nil +} + func (enc *encoder) idForAttr(attr string) uint16 { if attr == "uid" && enc.uidAttr > 0 { return enc.uidAttr @@ -891,9 +953,10 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { } } - for _, slice := range parentSlice { + for i, slice := range parentSlice { + // sort the slice + enc.MergeSort(&slice) // From every slice we need to remove node with attribute "uid". - MergeSort(&slice, enc) var prev, cur fastJsonNode cur = slice for cur != nil { @@ -912,78 +975,12 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { if prev == nil { slice = nil } + parentSlice[i] = slice } return parentSlice, nil } -func MergeSort(headRef *fastJsonNode, enc *encoder) { - head := *headRef - var a fastJsonNode - var b fastJsonNode - - /* Base case -- length 0 or 1 */ - if headRef == nil || (*headRef).next == nil { - return - } - - /* Split head into 'a' and 'b' sublists */ - FrontBackSplit(head, &a, &b) - - /* Recursively sort the sublists */ - MergeSort(&a, enc) - MergeSort(&b, enc) - - /* answer = merge the two sorted lists together */ - *headRef = SortedMerge(a, b, enc) -} - -func SortedMerge(a fastJsonNode, b fastJsonNode, enc *encoder) fastJsonNode { - var result fastJsonNode - - /* Base cases */ - if a == nil { - return b - } else if b == nil { - return a - } - - /* Pick either a or b, and recur */ - if Less(enc, a, b) { - result = a - result.next = SortedMerge(a.next, b, enc) - } else { - result = b - result.next = SortedMerge(a, b.next, enc) - } - return result -} - -func Less(enc *encoder, i fastJsonNode, j fastJsonNode) bool { - attri := enc.getAttr(i) - attrj := enc.getAttr(j) - cmp := strings.Compare(enc.attrForID(attri), enc.attrForID(attrj)) - return cmp < 0 -} - -func FrontBackSplit(source fastJsonNode, - frontRef *fastJsonNode, backRef *fastJsonNode) { - slow := source - fast := source.next - - for fast != nil { - fast = fast.next - if fast != nil { - slow = slow.next - fast = fast.next - } - } - - *frontRef = source - *backRef = slow.next - slow.next = nil -} - func (sg *SubGraph) addGroupby(enc *encoder, fj fastJsonNode, res *groupResults, fname string) error { From 14640718972f3627d85b7e5122e1118ed86dcc7c Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 30 Mar 2021 17:51:13 +0530 Subject: [PATCH 10/14] clean code --- query/outputnode.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index cfd9312ccdb..48a4711d84a 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -955,7 +955,7 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { for i, slice := range parentSlice { // sort the slice - enc.MergeSort(&slice) + enc.MergeSort(&parentSlice[i]) // From every slice we need to remove node with attribute "uid". var prev, cur fastJsonNode cur = slice @@ -975,7 +975,6 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { if prev == nil { slice = nil } - parentSlice[i] = slice } return parentSlice, nil From 60424c9641cd5f94af663e9900aa3db51f5fd2c5 Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 30 Mar 2021 18:36:51 +0530 Subject: [PATCH 11/14] clean code --- query/outputnode.go | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 48a4711d84a..b23cd5e945c 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -156,19 +156,19 @@ func (enc *encoder) MergeSort(headRef *fastJsonNode) { var a fastJsonNode var b fastJsonNode - if headRef == nil || (*headRef).next == nil { + if headRef == nil || head.next == nil { return } - FrontBackSplit(head, &a, &b) + frontBackSplit(head, &a, &b) enc.MergeSort(&a) enc.MergeSort(&b) - *headRef = enc.SortedMerge(a, b) + *headRef = enc.sortedMerge(a, b) } -func (enc *encoder) SortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode { +func (enc *encoder) sortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode { var result fastJsonNode if a == nil { @@ -177,24 +177,23 @@ func (enc *encoder) SortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode { return a } - if enc.Less(a, b) { + if enc.less(a, b) { result = a - result.next = enc.SortedMerge(a.next, b) + result.next = enc.sortedMerge(a.next, b) } else { result = b - result.next = enc.SortedMerge(a, b.next) + result.next = enc.sortedMerge(a, b.next) } return result } -func (enc *encoder) Less(i fastJsonNode, j fastJsonNode) bool { +func (enc *encoder) less(i fastJsonNode, j fastJsonNode) bool { attri := enc.getAttr(i) attrj := enc.getAttr(j) - cmp := strings.Compare(enc.attrForID(attri), enc.attrForID(attrj)) - return cmp <= 0 + return strings.Compare(enc.attrForID(attri), enc.attrForID(attrj)) <= 0 } -func FrontBackSplit(source fastJsonNode, +func frontBackSplit(source fastJsonNode, frontRef *fastJsonNode, backRef *fastJsonNode) { slow := source fast := source.next @@ -953,16 +952,18 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { } } - for i, slice := range parentSlice { - // sort the slice + for i, node := range parentSlice { + // sort the fastJson list + // This will ensure that nodes with same attribute name comes together + // in response enc.MergeSort(&parentSlice[i]) - // From every slice we need to remove node with attribute "uid". + // From every list we need to remove node with attribute "uid". var prev, cur fastJsonNode - cur = slice + cur = node for cur != nil { if enc.getAttr(cur) == enc.uidAttr { if prev == nil { - slice = cur + node = cur cur = cur.next continue } else { @@ -973,7 +974,7 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { cur = cur.next } if prev == nil { - slice = nil + node = nil } } From 0754400aeac936e389bd010466f8614149fb7e2f Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 30 Mar 2021 18:46:26 +0530 Subject: [PATCH 12/14] clean code --- query/outputnode.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index b23cd5e945c..4075d75fc7c 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -952,18 +952,17 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { } } - for i, node := range parentSlice { + for i, slice := range parentSlice { // sort the fastJson list - // This will ensure that nodes with same attribute name comes together - // in response + // This will ensure that nodes with same attribute name comes together in response enc.MergeSort(&parentSlice[i]) // From every list we need to remove node with attribute "uid". var prev, cur fastJsonNode - cur = node + cur = slice for cur != nil { if enc.getAttr(cur) == enc.uidAttr { if prev == nil { - node = cur + slice = cur cur = cur.next continue } else { @@ -974,7 +973,7 @@ func (enc *encoder) normalize(fj fastJsonNode) ([]fastJsonNode, error) { cur = cur.next } if prev == nil { - node = nil + slice = nil } } From ad5e831773dd9a3c9316a784268eba1cae012bec Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 30 Mar 2021 21:21:51 +0530 Subject: [PATCH 13/14] addressed Manish comments --- query/outputnode.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/query/outputnode.go b/query/outputnode.go index 4075d75fc7c..fe6b88a1144 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -153,22 +153,19 @@ func newEncoder() *encoder { // Sort the given fastJson list func (enc *encoder) MergeSort(headRef *fastJsonNode) { head := *headRef - var a fastJsonNode - var b fastJsonNode - if headRef == nil || head.next == nil { return } + var a, b fastJsonNode frontBackSplit(head, &a, &b) - enc.MergeSort(&a) enc.MergeSort(&b) - *headRef = enc.sortedMerge(a, b) + *headRef = enc.mergeSortedLists(a, b) } -func (enc *encoder) sortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode { +func (enc *encoder) mergeSortedLists(a fastJsonNode, b fastJsonNode) fastJsonNode { var result fastJsonNode if a == nil { @@ -179,10 +176,10 @@ func (enc *encoder) sortedMerge(a fastJsonNode, b fastJsonNode) fastJsonNode { if enc.less(a, b) { result = a - result.next = enc.sortedMerge(a.next, b) + result.next = enc.mergeSortedLists(a.next, b) } else { result = b - result.next = enc.sortedMerge(a, b.next) + result.next = enc.mergeSortedLists(a, b.next) } return result } From 19ce17b5c0ced0a1c6567ac24f4575bb695b232a Mon Sep 17 00:00:00 2001 From: JatinDevDG Date: Tue, 30 Mar 2021 21:23:53 +0530 Subject: [PATCH 14/14] clean code --- query/outputnode.go | 1 - 1 file changed, 1 deletion(-) diff --git a/query/outputnode.go b/query/outputnode.go index fe6b88a1144..1741e1ec5ee 100644 --- a/query/outputnode.go +++ b/query/outputnode.go @@ -161,7 +161,6 @@ func (enc *encoder) MergeSort(headRef *fastJsonNode) { frontBackSplit(head, &a, &b) enc.MergeSort(&a) enc.MergeSort(&b) - *headRef = enc.mergeSortedLists(a, b) }