github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/metacache-marker.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"strconv"
    24  	"strings"
    25  
    26  	"github.com/minio/minio/internal/logger"
    27  )
    28  
    29  // markerTagVersion is the marker version.
    30  // Should not need to be updated unless a fundamental change is made to the marker format.
    31  const markerTagVersion = "v2"
    32  
    33  // parseMarker will parse a marker possibly encoded with encodeMarker
    34  func (o *listPathOptions) parseMarker() {
    35  	s := o.Marker
    36  	if !strings.Contains(s, "[minio_cache:"+markerTagVersion) {
    37  		return
    38  	}
    39  	start := strings.LastIndex(s, "[")
    40  	o.Marker = s[:start]
    41  	end := strings.LastIndex(s, "]")
    42  	tag := strings.Trim(s[start:end], "[]")
    43  	tags := strings.Split(tag, ",")
    44  	for _, tag := range tags {
    45  		kv := strings.Split(tag, ":")
    46  		if len(kv) < 2 {
    47  			continue
    48  		}
    49  		switch kv[0] {
    50  		case "minio_cache":
    51  			if kv[1] != markerTagVersion {
    52  				continue
    53  			}
    54  		case "id":
    55  			o.ID = kv[1]
    56  		case "return":
    57  			o.ID = mustGetUUID()
    58  			o.Create = true
    59  		case "p": // pool
    60  			v, err := strconv.ParseInt(kv[1], 10, 64)
    61  			if err != nil {
    62  				o.ID = mustGetUUID()
    63  				o.Create = true
    64  				continue
    65  			}
    66  			o.pool = int(v)
    67  		case "s": // set
    68  			v, err := strconv.ParseInt(kv[1], 10, 64)
    69  			if err != nil {
    70  				o.ID = mustGetUUID()
    71  				o.Create = true
    72  				continue
    73  			}
    74  			o.set = int(v)
    75  		default:
    76  			// Ignore unknown
    77  		}
    78  	}
    79  }
    80  
    81  // encodeMarker will encode a uuid and return it as a marker.
    82  // uuid cannot contain '[', ':' or ','.
    83  func (o listPathOptions) encodeMarker(marker string) string {
    84  	if o.ID == "" {
    85  		// Mark as returning listing...
    86  		return fmt.Sprintf("%s[minio_cache:%s,return:]", marker, markerTagVersion)
    87  	}
    88  	if strings.ContainsAny(o.ID, "[:,") {
    89  		logger.LogIf(context.Background(), fmt.Errorf("encodeMarker: uuid %s contained invalid characters", o.ID))
    90  	}
    91  	return fmt.Sprintf("%s[minio_cache:%s,id:%s,p:%d,s:%d]", marker, markerTagVersion, o.ID, o.pool, o.set)
    92  }