improve sorting efficiency

pull/58/head
Ibrahim Mbaziira 2018-11-04 22:29:40 +03:00
parent 5fdad5c19f
commit dba032d5e7
No known key found for this signature in database
GPG Key ID: AD2F94CDEA5F7863
1 changed files with 25 additions and 33 deletions

View File

@ -306,8 +306,9 @@ func (r *RuntimeSort) OriginalPosition(ix int) int {
}
type TableSorter struct {
field string
obj *metav1beta1.Table
field string
obj *metav1beta1.Table
parsedRows [][][]reflect.Value
}
func (t *TableSorter) Len() int {
@ -319,32 +320,8 @@ func (t *TableSorter) Swap(i, j int) {
}
func (t *TableSorter) Less(i, j int) bool {
iObj := t.obj.Rows[i].Object.Object
jObj := t.obj.Rows[j].Object.Object
var iValues [][]reflect.Value
var jValues [][]reflect.Value
var err error
parser := jsonpath.New("sorting").AllowMissingKeys(true)
err = parser.Parse(t.field)
if err != nil {
glog.Fatalf("sorting error: %v\n", err)
}
// TODO(juanvallejo): this is expensive for very large sets.
// To improve runtime complexity, build an array which contains all
// resolved fields, and sort that instead.
iValues, err = findJSONPathResults(parser, iObj)
if err != nil {
glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, t.field, err)
}
jValues, err = findJSONPathResults(parser, jObj)
if err != nil {
glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, t.field, err)
}
iValues := t.parsedRows[i]
jValues := t.parsedRows[j]
if len(iValues) == 0 || len(iValues[0]) == 0 || len(jValues) == 0 || len(jValues[0]) == 0 {
glog.Fatalf("couldn't find any field with path %q in the list of objects", t.field)
}
@ -354,7 +331,7 @@ func (t *TableSorter) Less(i, j int) bool {
less, err := isLess(iField, jField)
if err != nil {
glog.Fatalf("Field %s in %T is an unsortable type: %s, err: %v", t.field, iObj, iField.Kind().String(), err)
glog.Fatalf("Field %s in %T is an unsortable type: %s, err: %v", t.field, t.parsedRows, iField.Kind().String(), err)
}
return less
}
@ -365,16 +342,31 @@ func (t *TableSorter) Sort() error {
}
func NewTableSorter(table *metav1beta1.Table, field string) *TableSorter {
var parsedRows [][][]reflect.Value
parser := jsonpath.New("sorting").AllowMissingKeys(true)
err := parser.Parse(field)
if err != nil {
glog.Fatalf("sorting error: %v\n", err)
}
for i := range table.Rows {
parsedRow, err := findJSONPathResults(parser, table.Rows[i].Object.Object)
if err != nil {
glog.Fatalf("Failed to get values for %#v using %s (%#v)", parsedRow, field, err)
}
parsedRows = append(parsedRows, parsedRow)
}
return &TableSorter{
obj: table,
field: field,
obj: table,
field: field,
parsedRows: parsedRows,
}
}
func findJSONPathResults(parser *jsonpath.JSONPath, from runtime.Object) ([][]reflect.Value, error) {
if unstructuredObj, ok := from.(*unstructured.Unstructured); ok {
return parser.FindResults(unstructuredObj.Object)
}
return parser.FindResults(reflect.ValueOf(from).Elem().Interface())
}