mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 11:28:24 +00:00 
			
		
		
		
	* Dropped unused codekit config * Integrated dynamic and static bindata for public * Ignore public bindata * Add a general generate make task * Integrated flexible public assets into web command * Updated vendoring, added all missiong govendor deps * Made the linter happy with the bindata and dynamic code * Moved public bindata definition to modules directory * Ignoring the new bindata path now * Updated to the new public modules import path * Updated public bindata command and drop the new prefix
		
			
				
	
	
		
			234 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package themis
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"sort"
 | |
| 
 | |
| 	"github.com/juju/errors"
 | |
| 	"github.com/ngaut/log"
 | |
| 	"github.com/pingcap/go-hbase"
 | |
| 	"github.com/pingcap/go-hbase/proto"
 | |
| )
 | |
| 
 | |
| type mutationValuePair struct {
 | |
| 	typ   hbase.Type
 | |
| 	value []byte
 | |
| }
 | |
| 
 | |
| func (mp *mutationValuePair) String() string {
 | |
| 	return fmt.Sprintf("type: %d value: %s", mp.typ, mp.value)
 | |
| }
 | |
| 
 | |
| type columnMutation struct {
 | |
| 	*hbase.Column
 | |
| 	*mutationValuePair
 | |
| }
 | |
| 
 | |
| func getEntriesFromDel(p *hbase.Delete) ([]*columnMutation, error) {
 | |
| 	errMsg := "must set at least one column for themis delete"
 | |
| 	if len(p.FamilyQuals) == 0 {
 | |
| 		return nil, errors.New(errMsg)
 | |
| 	}
 | |
| 
 | |
| 	var ret []*columnMutation
 | |
| 	for f, _ := range p.Families {
 | |
| 		quilifiers := p.FamilyQuals[f]
 | |
| 		if len(quilifiers) == 0 {
 | |
| 			return nil, errors.New(errMsg)
 | |
| 		}
 | |
| 		for q, _ := range quilifiers {
 | |
| 			mutation := &columnMutation{
 | |
| 				Column: &hbase.Column{
 | |
| 					Family: []byte(f),
 | |
| 					Qual:   []byte(q),
 | |
| 				},
 | |
| 				mutationValuePair: &mutationValuePair{
 | |
| 					typ: hbase.TypeDeleteColumn,
 | |
| 				},
 | |
| 			}
 | |
| 			ret = append(ret, mutation)
 | |
| 		}
 | |
| 	}
 | |
| 	return ret, nil
 | |
| }
 | |
| 
 | |
| func getEntriesFromPut(p *hbase.Put) []*columnMutation {
 | |
| 	var ret []*columnMutation
 | |
| 	for i, f := range p.Families {
 | |
| 		qualifiers := p.Qualifiers[i]
 | |
| 		for j, q := range qualifiers {
 | |
| 			mutation := &columnMutation{
 | |
| 				Column: &hbase.Column{
 | |
| 					Family: f,
 | |
| 					Qual:   q,
 | |
| 				},
 | |
| 				mutationValuePair: &mutationValuePair{
 | |
| 					typ:   hbase.TypePut,
 | |
| 					value: p.Values[i][j],
 | |
| 				},
 | |
| 			}
 | |
| 			ret = append(ret, mutation)
 | |
| 		}
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| func (cm *columnMutation) toCell() *proto.Cell {
 | |
| 	ret := &proto.Cell{
 | |
| 		Family:    cm.Family,
 | |
| 		Qualifier: cm.Qual,
 | |
| 		Value:     cm.value,
 | |
| 	}
 | |
| 	if cm.typ == hbase.TypePut { // put
 | |
| 		ret.CellType = proto.CellType_PUT.Enum()
 | |
| 	} else if cm.typ == hbase.TypeMinimum { // onlyLock
 | |
| 		ret.CellType = proto.CellType_MINIMUM.Enum()
 | |
| 	} else { // delete, themis delete API only support delete column
 | |
| 		ret.CellType = proto.CellType_DELETE_COLUMN.Enum()
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| type rowMutation struct {
 | |
| 	tbl []byte
 | |
| 	row []byte
 | |
| 	// mutations := { 'cf:col' => mutationValuePair }
 | |
| 	mutations map[string]*mutationValuePair
 | |
| }
 | |
| 
 | |
| func (r *rowMutation) getColumns() []hbase.Column {
 | |
| 	var ret []hbase.Column
 | |
| 	for k, _ := range r.mutations {
 | |
| 		c := &hbase.Column{}
 | |
| 		// TODO: handle error, now just ignore
 | |
| 		if err := c.ParseFromString(k); err != nil {
 | |
| 			log.Warnf("parse from string error, column: %s, mutation: %s, error: %v", c, k, err)
 | |
| 		}
 | |
| 		ret = append(ret, *c)
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| func (r *rowMutation) getSize() int {
 | |
| 	return len(r.mutations)
 | |
| }
 | |
| 
 | |
| func (r *rowMutation) getType(c hbase.Column) hbase.Type {
 | |
| 	p, ok := r.mutations[c.String()]
 | |
| 	if !ok {
 | |
| 		return hbase.TypeMinimum
 | |
| 	}
 | |
| 	return p.typ
 | |
| }
 | |
| 
 | |
| func newRowMutation(tbl, row []byte) *rowMutation {
 | |
| 	return &rowMutation{
 | |
| 		tbl:       tbl,
 | |
| 		row:       row,
 | |
| 		mutations: map[string]*mutationValuePair{},
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (r *rowMutation) addMutation(c *hbase.Column, typ hbase.Type, val []byte, onlyLock bool) {
 | |
| 	// 3 scene: put, delete, onlyLock
 | |
| 	// if it is onlyLock scene, then has not data modify, when has contained the qualifier, can't replace exist value,
 | |
| 	// becuase put or delete operation has add mutation
 | |
| 	if onlyLock && r.mutations[c.String()] != nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	r.mutations[c.String()] = &mutationValuePair{
 | |
| 		typ:   typ,
 | |
| 		value: val,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (r *rowMutation) mutationList(withValue bool) []*columnMutation {
 | |
| 	var ret []*columnMutation
 | |
| 	var keys []string
 | |
| 	for k, _ := range r.mutations {
 | |
| 		keys = append(keys, k)
 | |
| 	}
 | |
| 	sort.Strings(keys)
 | |
| 	for _, k := range keys {
 | |
| 		v := &mutationValuePair{
 | |
| 			typ: r.mutations[k].typ,
 | |
| 		}
 | |
| 		if withValue {
 | |
| 			v.value = r.mutations[k].value
 | |
| 		}
 | |
| 		c := &hbase.Column{}
 | |
| 		// TODO: handle error, now just ignore
 | |
| 		if err := c.ParseFromString(k); err != nil {
 | |
| 			log.Warnf("parse from string error, column: %s, mutation: %s, error: %v", c, k, err)
 | |
| 		}
 | |
| 		ret = append(ret, &columnMutation{
 | |
| 			Column:            c,
 | |
| 			mutationValuePair: v,
 | |
| 		})
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| type columnMutationCache struct {
 | |
| 	// mutations => {table => { rowKey => row mutations } }
 | |
| 	mutations map[string]map[string]*rowMutation
 | |
| }
 | |
| 
 | |
| func newColumnMutationCache() *columnMutationCache {
 | |
| 	return &columnMutationCache{
 | |
| 		mutations: map[string]map[string]*rowMutation{},
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (c *columnMutationCache) addMutation(tbl []byte, row []byte, col *hbase.Column, t hbase.Type, v []byte, onlyLock bool) {
 | |
| 	tblRowMutations, ok := c.mutations[string(tbl)]
 | |
| 	if !ok {
 | |
| 		// create table mutation map
 | |
| 		tblRowMutations = map[string]*rowMutation{}
 | |
| 		c.mutations[string(tbl)] = tblRowMutations
 | |
| 	}
 | |
| 
 | |
| 	rowMutations, ok := tblRowMutations[string(row)]
 | |
| 	if !ok {
 | |
| 		// create row mutation map
 | |
| 		rowMutations = newRowMutation(tbl, row)
 | |
| 		tblRowMutations[string(row)] = rowMutations
 | |
| 	}
 | |
| 	rowMutations.addMutation(col, t, v, onlyLock)
 | |
| }
 | |
| 
 | |
| func (c *columnMutationCache) getMutation(cc *hbase.ColumnCoordinate) *mutationValuePair {
 | |
| 	t, ok := c.mutations[string(cc.Table)]
 | |
| 	if !ok {
 | |
| 		return nil
 | |
| 	}
 | |
| 	rowMutation, ok := t[string(cc.Row)]
 | |
| 	if !ok {
 | |
| 		return nil
 | |
| 	}
 | |
| 	p, ok := rowMutation.mutations[cc.GetColumn().String()]
 | |
| 	if !ok {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return p
 | |
| }
 | |
| 
 | |
| func (c *columnMutationCache) getRowCount() int {
 | |
| 	ret := 0
 | |
| 	for _, v := range c.mutations {
 | |
| 		ret += len(v)
 | |
| 	}
 | |
| 	return ret
 | |
| }
 | |
| 
 | |
| func (c *columnMutationCache) getMutationCount() int {
 | |
| 	ret := 0
 | |
| 	for _, v := range c.mutations {
 | |
| 		for _, vv := range v {
 | |
| 			ret += len(vv.mutationList(false))
 | |
| 		}
 | |
| 	}
 | |
| 	return ret
 | |
| }
 |