github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/frame/memframe/memframe.go (about)

     1  // Copyright 2015 The Neugram Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package memframe
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"math/big"
    12  
    13  	"neugram.io/ng/frame"
    14  )
    15  
    16  /*
    17  type Int struct {
    18  	Data   []big.Int
    19  	Stride int
    20  	Rect   Rectangle
    21  }
    22  
    23  type Float64 struct {
    24  	Data   []float64
    25  	Stride int
    26  	Rect   Rectangle
    27  }
    28  */
    29  
    30  type Memory struct {
    31  	ColName []string
    32  	//ColType []frame.Type TODO
    33  	Data   []interface{}
    34  	Stride int
    35  	Width  int
    36  	Height int
    37  }
    38  
    39  func New(width, height int) *Memory {
    40  	return &Memory{
    41  		ColName: make([]string, width),
    42  		Data:    make([]interface{}, width*height),
    43  		Stride:  width,
    44  		Width:   width,
    45  		Height:  height,
    46  	}
    47  }
    48  
    49  func NewLiteral(colName []string, data [][]interface{}) *Memory {
    50  	d := New(len(colName), len(data))
    51  	d.ColName = append([]string{}, colName...)
    52  	for i, row := range data {
    53  		if len(row) != len(colName) {
    54  			panic(fmt.Sprintf("memframe.NewLiteral: row %d length is %d, want %d", i, len(row), len(colName)))
    55  		}
    56  		copy(d.Data[i*d.Stride:], row)
    57  	}
    58  	return d
    59  }
    60  
    61  var errPtrNil = errors.New("pointer is nil")
    62  
    63  func assign(dst, src interface{}) error {
    64  	if dst, ok := dst.(*interface{}); ok {
    65  		*dst = src
    66  		return nil
    67  	}
    68  
    69  	switch src := src.(type) {
    70  	case string:
    71  		switch dst := dst.(type) {
    72  		case *string:
    73  			if dst == nil {
    74  				return errPtrNil
    75  			}
    76  			*dst = src
    77  			return nil
    78  		}
    79  		// TODO case []byte?
    80  	case int:
    81  		switch dst := dst.(type) {
    82  		case *int:
    83  			if dst == nil {
    84  				return errPtrNil
    85  			}
    86  			*dst = src
    87  			return nil
    88  		case *int64:
    89  			if dst == nil {
    90  				return errPtrNil
    91  			}
    92  			*dst = int64(src)
    93  			return nil
    94  		case *big.Int:
    95  			if dst == nil {
    96  				return errPtrNil
    97  			}
    98  			dst.SetInt64(int64(src))
    99  			return nil
   100  		}
   101  	case float64:
   102  		switch dst := dst.(type) {
   103  		case *float64:
   104  			if dst == nil {
   105  				return errPtrNil
   106  			}
   107  			*dst = src
   108  			return nil
   109  		case *big.Float:
   110  			if dst == nil {
   111  				return errPtrNil
   112  			}
   113  			dst.SetFloat64(src)
   114  			return nil
   115  		}
   116  	case complex128:
   117  		switch dst := dst.(type) {
   118  		case *complex128:
   119  			if dst == nil {
   120  				return errPtrNil
   121  			}
   122  			*dst = src
   123  			return nil
   124  		}
   125  	case *big.Int:
   126  		switch dst := dst.(type) {
   127  		case *big.Int:
   128  			if dst == nil {
   129  				return errPtrNil
   130  			}
   131  			dst.Set(src)
   132  			return nil
   133  		case *big.Float:
   134  			if dst == nil {
   135  				return errPtrNil
   136  			}
   137  			dst.SetInt(src)
   138  			return nil
   139  		}
   140  	case *big.Float:
   141  		switch dst := dst.(type) {
   142  		case *big.Float:
   143  			if dst == nil {
   144  				return errPtrNil
   145  			}
   146  			dst.Set(src)
   147  			return nil
   148  		}
   149  	case nil:
   150  	}
   151  
   152  	return fmt.Errorf("assign: dst:%T, src:%T\n", dst, src)
   153  }
   154  
   155  func (d *Memory) offset(x, y int) int { return y*d.Stride + x }
   156  func (d *Memory) Get(x, y int, dst ...interface{}) error {
   157  	if y >= d.Height {
   158  		return io.EOF
   159  	}
   160  	for i, dst := range dst {
   161  		// TODO use frame.Type?
   162  		if err := assign(dst, d.Data[d.offset(x+i, y)]); err != nil {
   163  			return fmt.Errorf("memframe: Get(%d, %d, ... %d:%T): %v", x, y, i, dst, err)
   164  		}
   165  	}
   166  	return nil
   167  }
   168  
   169  func (d *Memory) Cols() []string { return d.ColName }
   170  
   171  func (d *Memory) Len() (int, error) { return d.Height, nil }
   172  
   173  func (d *Memory) Set(x, y int, vals ...interface{}) error {
   174  	if y >= d.Height { // Grow
   175  		data := make([]interface{}, d.Stride*(y+1))
   176  		copy(data, d.Data)
   177  		d.Data = data
   178  		d.Height = y + 1
   179  	}
   180  	// TODO check for valid types
   181  	if len(vals)+x > d.Width {
   182  		return fmt.Errorf("memframe.Set(%d, y, len=%d) called for frame width %d", x, len(vals), d.Width)
   183  	}
   184  	copy(d.Data[d.offset(x, y):], vals)
   185  	return nil
   186  }
   187  
   188  func (d *Memory) Slice(x, xlen, y, ylen int) frame.Frame {
   189  	if ylen == -1 {
   190  		ylen = d.Height
   191  	}
   192  	return &Memory{
   193  		ColName: d.ColName[x : x+xlen],
   194  		Data:    d.Data[d.offset(x, y):],
   195  		Stride:  d.Stride,
   196  		Width:   xlen,
   197  		Height:  ylen,
   198  	}
   199  }