github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/codec/perfield/docValuesFormat.go (about)

     1  package perfield
     2  
     3  import (
     4  	. "github.com/balzaczyy/golucene/core/codec/spi"
     5  	. "github.com/balzaczyy/golucene/core/index/model"
     6  	"github.com/balzaczyy/golucene/core/util"
     7  	"io"
     8  )
     9  
    10  // perfield/PerFieldDocValuesFormat.java
    11  
    12  /*
    13  Enables per field docvalues support,
    14  
    15  Note, when extending this class, the name Name() is written into the
    16  index. In order for the field to be read, the name must resolve to
    17  your implementation via LoadXYZ(). This method use hard-coded map to
    18  resolve codec names.
    19  
    20  Files written by each docvalues format have an additional suffix
    21  containing the format name. For example, in a per-field configuration
    22  instead of _1.dat fielnames would look like _1_Lucene40_0.dat.
    23  */
    24  type PerFieldDocValuesFormat struct {
    25  }
    26  
    27  func NewPerFieldDocValuesFormat(f func(field string) DocValuesFormat) *PerFieldDocValuesFormat {
    28  	return &PerFieldDocValuesFormat{}
    29  }
    30  
    31  func (pf *PerFieldDocValuesFormat) Name() string {
    32  	return "PerFieldDV40"
    33  }
    34  
    35  func (pf *PerFieldDocValuesFormat) FieldsConsumer(state *SegmentWriteState) (w DocValuesConsumer, err error) {
    36  	panic("not implemented yet")
    37  }
    38  
    39  func (pf *PerFieldDocValuesFormat) FieldsProducer(state SegmentReadState) (r DocValuesProducer, err error) {
    40  	return newPerFieldDocValuesReader(state)
    41  }
    42  
    43  func dvSuffix(format, suffix string) string {
    44  	return format + "_" + suffix
    45  }
    46  
    47  func dvFullSegmentSuffix(outerSuffix, suffix string) string {
    48  	if len(outerSuffix) == 0 {
    49  		return suffix
    50  	}
    51  	return outerSuffix + "_" + suffix
    52  }
    53  
    54  type PerFieldDocValuesReader struct {
    55  	fields  map[string]DocValuesProducer
    56  	formats map[string]DocValuesProducer
    57  }
    58  
    59  func newPerFieldDocValuesReader(state SegmentReadState) (dvp DocValuesProducer, err error) {
    60  	ans := PerFieldDocValuesReader{
    61  		make(map[string]DocValuesProducer), make(map[string]DocValuesProducer)}
    62  	// Read _X.per and init each format:
    63  	success := false
    64  	defer func() {
    65  		if !success {
    66  			fps := make([]DocValuesProducer, 0)
    67  			for _, v := range ans.formats {
    68  				fps = append(fps, v)
    69  			}
    70  			items := make([]io.Closer, len(fps))
    71  			for i, v := range fps {
    72  				items[i] = v
    73  			}
    74  			util.CloseWhileSuppressingError(items...)
    75  		}
    76  	}()
    77  	// Read field name -> format name
    78  	for _, fi := range state.FieldInfos.Values {
    79  		if fi.HasDocValues() {
    80  			fieldName := fi.Name
    81  			if formatName := fi.Attribute(PER_FIELD_FORMAT_KEY); formatName != "" {
    82  				// null formatName means the field is in fieldInfos, but has no docvalues!
    83  				suffix := fi.Attribute(PER_FIELD_SUFFIX_KEY)
    84  				// assert suffix != nil
    85  				segmentSuffix := dvFullSegmentSuffix(state.SegmentSuffix, dvSuffix(formatName, suffix))
    86  				if _, ok := ans.formats[segmentSuffix]; !ok {
    87  					newReadState := state // clone
    88  					newReadState.SegmentSuffix = formatName + "_" + suffix
    89  					if p, err := LoadDocValuesProducer(formatName, newReadState); err == nil {
    90  						ans.formats[segmentSuffix] = p
    91  					}
    92  				}
    93  				ans.fields[fieldName] = ans.formats[segmentSuffix]
    94  			}
    95  		}
    96  	}
    97  	success = true
    98  	return &ans, nil
    99  }
   100  
   101  func (dvp *PerFieldDocValuesReader) Numeric(field *FieldInfo) (v NumericDocValues, err error) {
   102  	if p, ok := dvp.fields[field.Name]; ok {
   103  		return p.Numeric(field)
   104  	}
   105  	return nil, nil
   106  }
   107  
   108  func (dvp *PerFieldDocValuesReader) Binary(field *FieldInfo) (v BinaryDocValues, err error) {
   109  	if p, ok := dvp.fields[field.Name]; ok {
   110  		return p.Binary(field)
   111  	}
   112  	return nil, nil
   113  }
   114  
   115  func (dvp *PerFieldDocValuesReader) Sorted(field *FieldInfo) (v SortedDocValues, err error) {
   116  	if p, ok := dvp.fields[field.Name]; ok {
   117  		return p.Sorted(field)
   118  	}
   119  	return nil, nil
   120  }
   121  
   122  func (dvp *PerFieldDocValuesReader) SortedSet(field *FieldInfo) (v SortedSetDocValues, err error) {
   123  	if p, ok := dvp.fields[field.Name]; ok {
   124  		return p.SortedSet(field)
   125  	}
   126  	return nil, nil
   127  }
   128  
   129  func (dvp *PerFieldDocValuesReader) Close() error {
   130  	fps := make([]DocValuesProducer, 0)
   131  	for _, v := range dvp.formats {
   132  		fps = append(fps, v)
   133  	}
   134  	items := make([]io.Closer, len(fps))
   135  	for i, v := range fps {
   136  		items[i] = v
   137  	}
   138  	return util.Close(items...)
   139  }