예제 #1
0
func (ls *libstore) GetList(key string) ([]string, error) {
	v := ls.getFromCache(key)
	if v != nil {
		return v.([]string), nil
	}

	// make args and reply
	var reply storagerpc.GetListReply
	args := storagerpc.GetArgs{
		Key: key,
	}

	if ls.needLease(key) {
		args.WantLease = true
		args.HostPort = ls.myHostPort
	}

	// do rpc
	rpcHandler := ls.getStorageRPCHandler(key)
	err := rpcHandler.Call(rpcNames[getListCall], &args, &reply)
	if err != nil {
		return nil, err
	}

	switch reply.Status {
	case storagerpc.OK:
	case storagerpc.KeyNotFound:
		return nil, ErrorKeyNotFound
	case storagerpc.ItemNotFound:
		return nil, ErrorItemNotFound
	case storagerpc.WrongServer:
		return nil, ErrorWrongServer
	case storagerpc.ItemExists:
		return nil, ErrorItemExisits
	case storagerpc.NotReady:
		return nil, ErrorNotReady
	default:
		panic("")
	}

	// add to cache
	if reply.Lease.Granted {
		ls.cache.Lock()
		ls.cache.c[key] = &cachedItem{
			value:          reply.Value,
			expirationTime: time.Now().Add(time.Second * time.Duration(reply.Lease.ValidSeconds)),
		}
		ls.cache.Unlock()
	}

	return reply.Value, nil
}
예제 #2
0
func (pc *proxyCounter) GetList(args *storagerpc.GetArgs, reply *storagerpc.GetListReply) error {
	if pc.override {
		reply.Status = pc.overrideStatus
		return pc.overrideErr
	}
	byteCount := len(args.Key)
	if args.WantLease {
		atomic.AddUint32(&pc.leaseRequestCount, 1)
	}
	if pc.disableLease {
		args.WantLease = false
	}
	err := pc.srv.Call("StorageServer.GetList", args, reply)
	for _, s := range reply.Value {
		byteCount += len(s)
	}
	if reply.Lease.Granted {
		if pc.overrideLeaseSeconds > 0 {
			reply.Lease.ValidSeconds = pc.overrideLeaseSeconds
		}
		atomic.AddUint32(&pc.leaseGrantedCount, 1)
	}
	atomic.AddUint32(&pc.rpcCount, 1)
	atomic.AddUint32(&pc.byteCount, uint32(byteCount))
	return err
}
예제 #3
0
파일: cache.go 프로젝트: oldady/Tribbler
func (cache *Cache) Get(key string, args *storagerpc.GetArgs) (interface{}, error) {
	///cache.mu.Lock()

	// it first clear the expired keys
	cache.Clear()

	// check if there exist key
	entry, ok := cache.datamap[key]

	if ok == false {
		///cache.mu.Unlock()

		entry = new(Entry)
		entry.query = list.New()
		entry.query.PushBack(time.Now())

		///cache.mu.Lock()
		cache.datamap[key] = entry

		///cache.mu.Unlock()
		return "", errors.New("KeyNotFound")
	}

	///cache.mu.Unlock()
	// check if lease is granted

	///entry.lock.Lock()
	if entry.granted == true {
		val := entry.val
		//cache.mu.Unlock()
		///entry.lock.Unlock()
		return val, nil
	}

	entry.query.PushBack(time.Now())

	if entry.query.Len() > storagerpc.QueryCacheThresh {
		args.WantLease = true
	}

	//cache.mu.Unlock()
	///entry.lock.Unlock()
	return "", errors.New("KeyNotFound")
}
예제 #4
0
func (ls *libstore) GetList(key string) ([]string, error) {
	var args storagerpc.GetArgs
	var reply storagerpc.GetListReply

	args.Key = key
	args.WantLease = false
	args.HostPort = ls.hostport

	// FIRST CHECK FROM LOCAL CACHE!!!
	val, err := ls.leases.Get(key, &args)
	if err == nil {
		return val.([]string), nil
	}

	// CHECK IF WE NEED LEASE
	if ls.mode == Always {
		args.WantLease = true
	} else if ls.mode == Never {
		args.WantLease = false
	}

	// pick the right server
	cli, err := ls.GetServer(key)
	if err != nil {
		return nil, err
	}

	// call rpc to storage server
	err = cli.Call("StorageServer.GetList", &args, &reply)
	if err != nil {
		return nil, err
	}

	// check reply status
	if reply.Status != storagerpc.OK {
		err = GetErrorType(reply.Status)
		return nil, err
	}

	// check if allow lease
	if reply.Lease.Granted {
		ls.leases.Insert(key, reply.Value, reply.Lease)
	}

	return reply.Value, nil
}
예제 #5
0
func (ls *libstore) Get(key string) (string, error) {
	var args storagerpc.GetArgs
	var reply storagerpc.GetReply

	//set wantlease to be false
	args.Key = key
	args.WantLease = false
	args.HostPort = ls.hostport

	// check if it is in cache
	val, err := ls.leases.Get(key, &args)
	if err == nil {
		return val.(string), nil
	}

	//CHECK IF WE NEED LEASE
	if ls.mode == Always {
		args.WantLease = true
	} else if ls.mode == Never {
		args.WantLease = false
	}

	// pick the right server
	cli, err := ls.GetServer(key)
	if err != nil {
		return "", err
	}

	// call rpc
	err = cli.Call("StorageServer.Get", &args, &reply)
	if err != nil {
		return "", err
	}

	if reply.Status != storagerpc.OK {
		err = GetErrorType(reply.Status)
		return "", err
	}

	// insert into cache
	if reply.Lease.Granted {
		ls.leases.Insert(key, reply.Value, reply.Lease)
	}

	return reply.Value, nil
}
예제 #6
0
func (cache *Cache) Get(args *storagerpc.GetArgs) (interface{}, error) {
	cache.lock.Lock()
	defer cache.lock.Unlock()

	cleanCache(cache, args.Key)

	entry, exist := cache.dataMap[args.Key]
	if !exist {
		entry = new(Entry)
		entry.queryList = new(list.List)
		entry.leaseIsVaild = false
		cache.dataMap[args.Key] = entry
	}
	entry.queryList.PushBack(time.Now())
	if entry.leaseIsVaild {
		cache.target++
		return entry.val, nil
	}

	if entry.queryList.Len() >= storagerpc.QueryCacheThresh {
		args.WantLease = true
	}
	return "", errors.New("key not in cache")
}
예제 #7
0
func (ls *libstore) GetList(key string) ([]string, error) {
	var args storagerpc.GetArgs
	var reply storagerpc.GetListReply

	args.Key = key
	args.WantLease = false
	args.HostPort = ls.hostport

	val, err := ls.localCache.Get(&args)
	if err == nil {
		return val.([]string), nil
	}

	if ls.mode == Always {
		args.WantLease = true
	} else if ls.mode == Never {
		args.WantLease = false
	}

	cli, err := ls.GetServer(key)
	if err != nil {
		return nil, err
	}

	err = cli.Call("StorageServer.GetList", &args, &reply)

	if err != nil {
		return nil, err
	}

	if reply.Status != storagerpc.OK {
		err = GetErrorType(reply.Status)
		return nil, err
	}

	if reply.Lease.Granted {
		ls.localCache.Put(key, reply.Value, reply.Lease)
	}
	return reply.Value, nil
}
예제 #8
0
func (ls *libstore) GetList(key string) ([]string, error) {
	var args storagerpc.GetArgs
	var reply storagerpc.GetListReply

	current_time := time.Now().Unix()

	// Check whether the key is in the cache
	// If yes, return directly
	ls.list_cache_locker.Lock()
	if list_cache_elem, ok := ls.list_cache[key]; ok {
		if list_cache_elem.lease_end >= current_time {
			ls.list_cache_locker.Unlock()
			return list_cache_elem.content, nil
		} else {
			delete(ls.list_cache, key)
		}
	}
	ls.list_cache_locker.Unlock()

	args.Key = key
	args.HostPort = ls.host_port

	if ls.lease_mode == Normal {
		ls.list_cache_locker.Lock()
		if query_list, ok := ls.query_record[key]; ok {
			query_list.PushBack(current_time)
		} else {
			new_list := list.New()
			new_list.PushBack(current_time)
			ls.query_record[key] = new_list
		}
		if query_list, ok := ls.query_record[key]; ok {
			for elem := query_list.Front(); elem != nil; elem = elem.Next() {
				if elem.Value.(int64)+storagerpc.QueryCacheSeconds < current_time {
					query_list.Remove(elem)
				} else {
					break
				}
			}
			if query_list.Len() >= storagerpc.QueryCacheThresh {
				args.WantLease = true
			} else {
				args.WantLease = false
			}
		}
		ls.list_cache_locker.Unlock()
	} else if ls.lease_mode == Always {
		args.WantLease = true
	}

	target_server := ls.GetServerIndex(key)
	ls.rpc_connection[target_server].Call("StorageServer.GetList", args, &reply)
	if reply.Status != storagerpc.OK {
		return nil, errors.New("Error in Getlist")
	}
	if reply.Lease.Granted {
		ls.list_cache_locker.Lock()
		defer ls.list_cache_locker.Unlock()
		ls.list_cache[key] = &ListCacheElement{lease_end: time.Now().Unix() + int64(reply.Lease.ValidSeconds), content: reply.Value}
	}
	return reply.Value, nil
}