123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- package lib
- import (
- "bytes"
- "encoding/json"
- )
- //topicPointer and textPointer should not be exported
- //mb move tweet reconstruction to dbRead from servers
- type Tweet struct {
- TopicPointer string
- TextPointer int
- Topics []string
- Text string
- RoundPosted int
- }
- var dbR = make(map[string][]Tweet)
- var archive = make(map[string][]Tweet)
- //has to be dividable by 32
- var minimumBlockSize int
- const roundsBeforeArchiving = 3
- var topicList []string
- var archiveTopicList []string
- func NewEntries(inputTweets []Tweet, whereTo int) {
- tmpdb := dbR
- if whereTo == 1 {
- tmpdb = archive
- }
- var position int = 0
- for _, tweet := range inputTweets {
- for index := range tweet.Topics {
- //new topic
- if _, ok := tmpdb[tweet.Topics[index]]; !ok {
- if whereTo == 0 {
- topicList = append(topicList, tweet.Topics[index])
- } else {
- archiveTopicList = append(archiveTopicList, tweet.Topics[index])
- }
- }
- //new tweet
- if index == 0 {
- position = len(tmpdb[tweet.Topics[0]])
- tmpdb[tweet.Topics[index]] = append(tmpdb[tweet.Topics[0]], tweet)
- } else {
- //known tweet
- //setting pointer for all other Topics
- topic := tweet.Topics[index]
- tweet.TopicPointer = tweet.Topics[0]
- tweet.TextPointer = position
- tweet.Topics = nil
- tweet.Text = ""
- tmpdb[topic] = append(tmpdb[topic], tweet)
- }
- }
- }
- if whereTo == 0 {
- dbR = tmpdb
- } else {
- archive = tmpdb
- }
- }
- //todo! add round to pirquery only get tweets that have been posted from that round onward
- func GetTweets(pirQuery []byte, dataLength int, whereFrom int) []byte {
- tmpdb := dbR
- if whereFrom == 1 {
- tmpdb = archive
- }
- minimumBlockSize = dataLength * maxTweetAmount(whereFrom)
- var wantedTopics = getNamesForTopics(pirQuery, whereFrom)
- tweetsToReturn := make([][]Tweet, len(wantedTopics))
- for index, wantedTopic := range wantedTopics {
- for _, tweet := range tmpdb[wantedTopic] {
- //new Tweet
- if tweet.Text != "" {
- tweet.RoundPosted = 0
- tweetsToReturn[index] = append(tweetsToReturn[index], tweet)
- } else {
- //"copied" tweet
- //find tweet with pointers
- tweet = tmpdb[tweet.TopicPointer][tweet.TextPointer]
- tweet.RoundPosted = 0
- tweetsToReturn[index] = append(tweetsToReturn[index], tweet)
- }
- }
- }
- return tweetsToByteArray(tweetsToReturn)
- }
- func maxTweetAmount(whereFrom int) int {
- tmpdb := dbR
- if whereFrom == 1 {
- tmpdb = archive
- }
- var max int = 0
- for i := range tmpdb {
- nrOfTweets := len(dbR[i])
- if nrOfTweets > max {
- max = nrOfTweets
- }
- }
- return max
- }
- func getNamesForTopics(wantedIndices []byte, whereFrom int) []string {
- var topicNames []string
- tmpTopicList := topicList
- if whereFrom == 1 {
- tmpTopicList = archiveTopicList
- }
- for index, element := range wantedIndices {
- if element == 1 {
- topicNames = append(topicNames, tmpTopicList[index])
- }
- }
- return topicNames
- }
- //transform struct to byte array for sending
- func tweetsToByteArray(tweetsToReturn [][]Tweet) []byte {
- tweetsAsBytes := make([]byte, minimumBlockSize)
- for _, block := range tweetsToReturn {
- var tweetToAppend []byte
- for _, tweet := range block {
- for _, topic := range tweet.Topics {
- tweetToAppend = append(tweetToAppend, []byte(topic)...)
- tweetToAppend = append(tweetToAppend, ","...)
- }
- //replaces last with ";", bc there is text following and not another topic
- tweetToAppend = tweetToAppend[:len(tweetToAppend)-1]
- tweetToAppend = append(tweetToAppend, []byte(";")[0])
- tweetToAppend = append(tweetToAppend, []byte(tweet.Text)...)
- tweetToAppend = append(tweetToAppend, []byte(";")[0])
- }
- //adds padding
- for i := len(tweetToAppend); i < minimumBlockSize; i++ {
- tweetToAppend = append(tweetToAppend, []byte(";")[0])
- }
- Xor(tweetToAppend, tweetsAsBytes)
- }
- return tweetsAsBytes
- }
- //see func name
- func GetTopicList(whereFrom int) ([]byte, int) {
- tmpTopicList := topicList
- if whereFrom == 1 {
- tmpTopicList = archiveTopicList
- }
- if (len(tmpTopicList)) == 0 {
- return nil, 0
- }
- topicByteArray := new(bytes.Buffer)
- json.NewEncoder(topicByteArray).Encode(tmpTopicList)
- return topicByteArray.Bytes(), len(tmpTopicList)
- }
- //iterates through full dbR and moves old tweets to archive
- func CleanUpdbR(round int) {
- var tweetsToArchive []Tweet
- for j := range dbR {
- tweets := dbR[j]
- for i := len(tweets) - 1; i >= 0; i-- {
- if round-roundsBeforeArchiving == tweets[i].RoundPosted {
- //only adds the tweet to the archive when there is text
- if tweets[i].Text != "" {
- tweetsToArchive = append(tweetsToArchive, tweets[i])
- }
- //delets the tweet from the array
- tweets = append(tweets[:i], tweets[i+1:]...)
- }
- }
- dbR[j] = tweets
- }
- NewEntries(tweetsToArchive, 1)
- }
|