예제 #1
0
func (ts *Tribserver) GetTribbles(args *tribproto.GetTribblesArgs, reply *tribproto.GetTribblesReply) os.Error {
	//check if user exists
	lastJson, stat, err := ts.tm.GET(args.Userid + LAST)
	if err != nil {
		return err
	}
	if stat == storageproto.OK {
		last := new(int)
		err := json.Unmarshal(lastJson, last)
		if err != nil {
			return err
		}
		size := *last
		if size > 100 {
			size = 100
		}

		//get 100 latest tribbles from user and add to the reply arg
		reply.Tribbles = make([]tribproto.Tribble, size)
		for i := 0; i < size; i++ {
			tribbleId := fmt.Sprintf("%s:%d", args.Userid, *last)
			tribJson, stat, err := ts.tm.GET(tribbleId)
			if err != nil {
				return err
			}
			if stat == storageproto.OK {
				trib := new(tribproto.Tribble)
				err := json.Unmarshal(tribJson, trib)
				if err != nil {
					return err
				}
				reply.Tribbles[i] = *trib
			}
			*last--
		}
	} else {
		reply.Status = tribproto.ENOSUCHUSER
	}
	return nil
}
예제 #2
0
func (ts *Tribserver) GetTribblesBySubscription(args *tribproto.GetTribblesArgs, reply *tribproto.GetTribblesReply) os.Error {
	//check if user exists
	suscribJson, stat, err := ts.tm.GET(args.Userid + SUBSCRIPTIONS)
	if err != nil {
		return err
	}
	if stat == storageproto.OK {
		suscribers := make(map[string]bool)
		err = json.Unmarshal(suscribJson, &suscribers)
		if err != nil {
			return err
		}

		//make minheap to store recent tribbles
		recentTribs := vector.Vector(make([]interface{}, 0, 100))
		heap.Init(&recentTribs)
		level := 0
		hasTribs := false

		//continue adding tribbles to heap until we reach a 100 or no more tribbles
		for recentTribs.Len() < 100 {
			hasTribs = false

			//for each suscription, get the last tribble
			for subscriber, _ := range suscribers {
				s := new(string)
				err = json.Unmarshal([]byte(subscriber), s)
				if err != nil {
					return err
				}

				lastJson, _, err := ts.tm.GET(*s + LAST)
				if err != nil {
					return err
				}
				last := new(int)
				err = json.Unmarshal(lastJson, last)
				if err != nil {
					return err
				}
				*last -= level
				tribbleId := fmt.Sprintf("%s:%d", *s, *last)
				if *last > 0 {
					hasTribs = true
					tribJson, stat, err := ts.tm.GET(tribbleId)
					if err != nil {
						return err
					}
					if stat == storageproto.OK {
						trib := new(tribproto.Tribble)
						err = json.Unmarshal(tribJson, trib)
						if err != nil {
							return err
						}

						//add to tribble if more recent than oldest tribble in heap
						if recentTribs.Len() >= 100 && recentTribs[0].(tribproto.Tribble).Posted < trib.Posted {
							heap.Pop(&recentTribs)
							heap.Push(&recentTribs, trib)

							//add to tribble if less than 100 in heap
						} else if recentTribs.Len() < 100 {
							heap.Push(&recentTribs, trib)
						}
					}
				}
			}
			level++
			if !hasTribs {
				break
			}
		}
		reply.Tribbles = make([]tribproto.Tribble, recentTribs.Len())
		for i := recentTribs.Len() - 1; i >= 0; i-- {
			reply.Tribbles[i] = *(heap.Pop(&recentTribs).(*tribproto.Tribble))
		}
	} else {
		reply.Status = tribproto.ENOSUCHUSER
	}
	return nil
}