Created
March 5, 2011 14:33
-
-
Save ts-3156/856391 to your computer and use it in GitHub Desktop.
sample code to store too big data in datastore.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 一人分のTwitterUserData2を保存。既に保存されていた場合は重複して保存してしまう<br> | |
* 既存のデータをこのメソッド呼出より前に削除する必要あり<br> | |
* 削除せずに更新したほうが効率がよい | |
* @param data フォロー、フォロワー、データ作成日等を含むオブジェクト | |
* @param updateCount 更新回数。レガシーな理由によりこういう形になった | |
* @return 保存が成功したかどうか | |
*/ | |
public static boolean storeTwitterUserData2(TwitterUserData2 data, int updateCount){ | |
if(data == null || data.getFollowingUsers() == null || data.getFollowersUsers() == null || data.getCreatedDate() == null){ | |
log.warning(data.getName() + ", fail to store because of invalid data."); | |
return false; | |
} | |
boolean isStored = true; | |
long start = 0, end = 0; | |
start = System.currentTimeMillis(); | |
ArrayList<TwitterUserData2> dataToStore = new ArrayList<TwitterUserData2>(); | |
Date createdDate = data.getCreatedDate(); | |
Date updatedDate = null; | |
if(data.getUpdatedDate() != null) | |
updatedDate = data.getUpdatedDate(); | |
ArrayList<ArrayList<String>> followingList = TwitterUtil.separateUsers(data.getFollowingUsers(), 1500); | |
ArrayList<ArrayList<String>> followersList = TwitterUtil.separateUsers(data.getFollowersUsers(), 1500); | |
// ループの中にあると効率悪いから外にだしました 2011/03/08 | |
int loopLimit = Math.min(followingList.size(), followersList.size()); | |
for(int i = 0; i < loopLimit; i++){ | |
TwitterUserData2 d = new TwitterUserData2(data.getName(), followingList.get(i), followersList.get(i), createdDate); | |
if(i == 0){ | |
d.setRemovingUsers(data.getRemovingUsers()); | |
d.setRemovedUsers(data.getRemovedUsers()); | |
d.setNameToIdMap(data.getNameToIdMap()); | |
} | |
if(updatedDate != null) | |
d.setUpdatedDate(updatedDate); | |
dataToStore.add(d); | |
} | |
if(followingList.size() >= followersList.size()){ | |
for(int i = followersList.size(); i < followingList.size(); i++){ | |
TwitterUserData2 d = new TwitterUserData2(data.getName(), followingList.get(i), null, createdDate); | |
if(updatedDate != null) | |
d.setUpdatedDate(updatedDate); | |
dataToStore.add(d); | |
} | |
} | |
else{ | |
for(int i = followingList.size(); i < followersList.size(); i++){ | |
TwitterUserData2 d = new TwitterUserData2(data.getName(), null, followersList.get(i), createdDate); | |
if(updatedDate != null) | |
d.setUpdatedDate(updatedDate); | |
dataToStore.add(d); | |
} | |
} | |
isStored = store2(dataToStore, updateCount); | |
end = System.currentTimeMillis(); | |
if(isStored) | |
log.info(data.getName() + ", successfully stored., time: " + (double)(end - start)/1000 + "seconds"); | |
else | |
log.warning(data.getName() + ", fail to store., time: " + (double)(end - start)/1000 + "seconds"); | |
return isStored; | |
} | |
/** | |
* このトランザクションはデータの不整合を起こす可能性がある<br> | |
* その問題は他のメソッドで解消している。slim3を使ってグローバルなトランザクションを利用すれば | |
* この問題は解決するかも | |
* @param dataList ひとり分のデータを複数に分割したList | |
* @param updateCount | |
* @return | |
*/ | |
private static boolean store2(ArrayList<TwitterUserData2> dataList, int updateCount){ | |
boolean isStored = true; | |
PersistenceManager pm = PMF.get().getPersistenceManager(); | |
Transaction tx = pm.currentTransaction(); | |
ArrayList<TwitterUserData2Cupsul> dataToStore = new ArrayList<TwitterUserData2Cupsul>(dataList.size()); | |
for(int i = 0; i < dataList.size(); i++){ | |
TwitterUserData2Cupsul c = new TwitterUserData2Cupsul(dataList.get(i), dataList.size(), i); | |
if(dataList.get(i).getUpdatedDate() != null){ | |
c.setUpdatedDate(dataList.get(i).getUpdatedDate()); | |
} | |
c.setVersion(2); | |
c.setUpdateCount(updateCount); | |
dataToStore.add(c); | |
} | |
try { | |
for(TwitterUserData2Cupsul data: dataToStore){ | |
tx.begin(); | |
pm.makePersistent(data); | |
tx.commit(); | |
} | |
} finally { | |
if (tx.isActive()){ | |
tx.rollback(); | |
isStored = false; | |
} | |
pm.close(); | |
} | |
return isStored; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Math.min(followingList.size(), followersList.size()) 等ループ無いに計算式を入れるより、
事前に計算後に固定値としてループは回した方がよいです。
トランザクション処理もrollback等でエラーが出ることもあると思うのでtry-catchで囲んだ方がいいですが
そこまでするとコードがごてごてするかな?