Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Public Interfaces

Change to Existing APIs


Design Details

Changes to the MetaTable

  • Metatable now add ts2alias2name and newestAliasTs member variables
Code Block
type immutablemap_string2string struct{
    storemap    map[string]string
}

func (imstr2str * immutablemap_string2string) get(key string) (string, error){
    rstr,ok := imstr2str.storemap[key]
    if(!ok){
        return nil, fmt.Errorf("key not exist")
    }
    return rstr, nil
}

func (imstr2str * immutablemap_string2string) put(key string, val string) (string, error){
    return nil, fmt.Errorf("not allowed put in immutablemap")
}

type metatable struct{
    ...
    ts2alias2name map[Timestamp]immutablemap_string2string
    newestAliasTs Timestamp
    ...
}
  • GetCollectionByName add alias timestamp as parameter to select which alias2name map will be used in ts2alias2name.
  • Change to alias will add a new alias2name immutable map in ts2alias2name.
Code Block
func build(im * immutablemap_string2string) Builder{
    builder := &Builder{
        reference: im
        mutable:   nil
    }
    return builder
}

type Builder struct{
    reference    immutablemap_string2string
    mutable      map[string]string
}

func (bdr *Builder) maybeClone(){
    if bdr.reference != nil{
        bdr.mutable = make(map[string]string)
        for k,v := range bdr.reference.storemap{
            bdr.mutable[k] = v
        }
        
        bdr.reference = nil
    }
}

func (bdr *Builder) getnamefromalias(key string) (string, bool){
    bdr.maybeClone()
    return bdr.mutable[key]
}

func(bdr *Builder) putalias2name(key string, val string) (string, bool){
    bdr.maybeclone()
    var pre string
    if v,ok = bdr.mutable[key], ok{
        pre = v
    }else{
        pre = nil
    }
    bdr.mutable[key] = val
    return pre, ok
}

func(bdr *Builder) removealias2name(key string) (string, bool){
    bdr.maybeclone()
    var pre string
    if v,ok = bdr.mutable[key], ok{
        pre = v
        delete(bdr.mutable, key)
    }else{
        pre = nil
    }
    return pre, ok
}

func (bdr *Builder) build() immutablemap_string2string{
    if bdr.reference != nil{
        reference := bdr.reference
        bdr.reference = nil
        return reference
    }else{
        mutable = bdr.mutable
        bdr.mutable = nil
        res := & immutablemap_string2string{
            storemap:mutable
        }
        return res
    }
}

func (mt * metatable) addAlias(collectionAlias string, collectionName string) (string, error){
    mt.ddLock.Lock()
    defer mt.ddLock.Unlock()
    ...
    ts = getTimestamp()
    tspre = mt.newestAliasTs
    Bdr = build(mt.ts2alias2name[tspre])
    pre,ok := Bdr.putalias2name(collectionAlias, collectionName)
    if ok{
        return pre, fmt.Errorf("alias already exist when add alias") 
    }
    mt.ts2alias2name[ts] = Bdr.build()
    mt.newestAliasTs = ts
    ...
    return nil, nil
}

func (mt * metatable) dropAlias(collectionAlias string) (string, error){
    mt.ddLock.Lock()
    defer mt.ddLock.Unlock()
    ...
    ts = getTimestamp()
    tspre = mt.newestAliasTs
    Bdr = build(mt.ts2alias2name[tspre])
    pre,ok := Bdr.removealias2id(collectionAlias)
    if !ok{
        return nil, fmt.Errorf("alias not exist when drop alias") 
    }
    mt.ts2alias2name[ts] = Bdr.build()
    mt.newestAliasTs = ts
    ...
    return pre, nil
}

func (mt * metatable) alterAlias(collectionAlias string, collectionName string) (string, error){
    mt.ddLock.Lock()
    defer mt.ddLock.Unlock()
    ...
    ts = getTimestamp()
    tspre = mt.newestAliasTs
    Bdr = build(mt.ts2alias2name[tspre])
    pre,ok := Bdr.putalias2name(collectionAlias, collectionName)
    if !ok{
        return nil, fmt.Errorf("alias not exist when alter alias") 
    }
    mt.ts2alias2name[ts] = Bdr.build()
    mt.newestAliasTs = ts
    ...
    return pre, nil
}