Skip to content

Commit a8c5f3f

Browse files
committed
bloblib v0.0.4
1 parent 22d67d4 commit a8c5f3f

File tree

6 files changed

+122
-106
lines changed

6 files changed

+122
-106
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Packaged the core operations of the azure blob storage as a separated library, t
1212

1313

1414
## Features:
15+
* New Features since v0.0.4 :
16+
1517
* Support man operations of the container,virtual directory and blob. such as create, delete, list, read, write etc.
1618
* New extension class of the InputStream and OutputStream. add a new cache layer and is optimized for the blob read and write.
1719
* Use blob leases as the distributed locking mechanism across multiple nodes. The blob will be locked exclusively when it is written.

src/main/java/com/wesley/bloblib/BlobBufferedIns.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public class BlobBufferedIns extends InputStream {
3131

3232
boolean isBlobEOF = false;
3333

34+
/* get the parallel downloader instance */
35+
ParallelDownloader parallelDownloader = ParallelDownloader.getInstance();
36+
37+
3438
@SuppressWarnings("static-access")
3539
public BlobBufferedIns(BlobReqParams reqParams) throws BfsException {
3640
this.blob = BlobService.getBlobReference(reqParams);
@@ -216,10 +220,8 @@ public synchronized final byte[] downloadBlobChunk (int offset, long len) throws
216220
len = Math.min(blobSize - offset, len) ;
217221
dwLocalBuffer = new byte[(int) len];
218222
try {
219-
ParallelDownloader parallelDownloader = new ParallelDownloader(blob, offset, len);
220-
dwLocalBuffer = parallelDownloader.downloadBlobWithParallelThreads();
223+
dwLocalBuffer = parallelDownloader.downloadBlobWithParallelThreads(blob, offset, len);
221224
bytesDownloaded = dwLocalBuffer.length;
222-
parallelDownloader.destroy();
223225
} catch (Exception ex) {
224226
String errMessage = "Unexpected exception occurred when downloading from the blob : "
225227
+ this.fullBlobPath + ". " + ex.getMessage();

src/main/java/com/wesley/bloblib/BlobBufferedOus.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public class BlobBufferedOus extends OutputStream {
5050

5151
/* list of all block ids we will be uploading - need it for the commit at the end */
5252
List<BlockEntry> blockList;
53+
54+
/* get the parallel uploader instance */
55+
ParallelUploader parallelUploader = ParallelUploader.getInstance();
5356

5457
@SuppressWarnings("static-access")
5558
public BlobBufferedOus(BlobReqParams reqParams) throws BfsException, StorageException {
@@ -195,11 +198,10 @@ public synchronized final int uploadBlobChunk (byte[] rawData, int offset, int
195198
/* renew the lease firstly, otherwise the lease may be expired, this will cause error */
196199
blob.renewLease(accCondtion);
197200
if (BfsBlobType.BLOCKBLOB.equals(this.blobType)){
198-
ParallelUploader parallelUploader = new ParallelUploader(blob, offset, length, chunkNumber);
199-
parallelUploader.uploadBlobWithParallelThreads(rawData, blockList, accCondtion, leaseID);
201+
int uploadRes[] = parallelUploader.uploadBlobWithParallelThreads(rawData, blob, offset, length,
202+
blockList, accCondtion, leaseID, chunkNumber);
200203
/* update the chunk counter */
201-
chunkNumber = parallelUploader.chunkNumber;
202-
parallelUploader.destroy();
204+
chunkNumber = uploadRes[1];
203205
}
204206
else
205207
{

src/main/java/com/wesley/bloblib/BlobLib.java

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,7 @@
11
package com.wesley.bloblib;
22

3-
import java.io.BufferedReader;
4-
import java.io.FileReader;
5-
import java.io.FileWriter;
6-
import java.nio.charset.StandardCharsets;
7-
import java.util.ArrayList;
8-
import java.util.List;
9-
103
import org.pmw.tinylog.Logger;
114

12-
import com.eclipsesource.json.Json;
13-
import com.eclipsesource.json.JsonObject;
14-
import com.microsoft.azure.storage.blob.CloudBlob;
15-
import com.microsoft.azure.storage.file.ShareListingDetails;
16-
175
public class BlobLib {
186

197
@SuppressWarnings("static-access")
@@ -48,8 +36,8 @@ public static void main(String[] args) {
4836
// BlobBufferedIns bbIns = new BlobBufferedIns(insParams);
4937
// BlobReqParams ousParams = new BlobReqParams();
5038
// ousParams.setContainer("music2017");
51-
// ousParams.setBlob("blobfs-2017-11-21.log");
52-
// /* get the blob type */
39+
// ousParams.setBlob("blobfs-2017-11-23.log");
40+
//// /* get the blob type */
5341
// ousParams.setBfsBlobType(BfsBlobType.BLOCKBLOB);
5442
// BlobService.createBlob(ousParams);
5543
// BlobBufferedOus bbOus = new BlobBufferedOus(ousParams);
@@ -132,7 +120,7 @@ public static void main(String[] args) {
132120
// BfsBlobType bfsBlobType = pathPropeties.getBfsBlobType();
133121
// BfsPath bfsPath = new BfsPath("newtest");
134122
// PathProperties pathProperties = bfsPath.getBfsPathProperties();
135-
BlobReqParams delDirParams = new BlobReqParams();
123+
// BlobReqParams delDirParams = new BlobReqParams();
136124
// delDirParams.setContainer("orders");
137125
// delDirParams.setBlob("wx.txt");
138126
// BlobService.deleteBlob(delDirParams);
@@ -152,7 +140,7 @@ public static void main(String[] args) {
152140
// System.out.println("DELETE SUCCESSED!");
153141
// }
154142
System.out.println("You called the main method!");
155-
System.out.println(Configuration.BFS_CACHE_TTL_MS);
143+
//System.out.println(Configuration.BFS_CACHE_TTL_MS);
156144
// while(true)
157145
// {
158146
// System.out.println("main thread!");
@@ -164,5 +152,5 @@ public static void main(String[] args) {
164152
Logger.error(ex.getMessage());
165153
}
166154
}
167-
155+
168156
}

src/main/java/com/wesley/bloblib/ParallelDownloader.java

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,17 @@
1616
*/
1717
public class ParallelDownloader {
1818

19-
/* the blob reference */
20-
private CloudBlob blob;
19+
/* instance of the object */
20+
private static ParallelDownloader instance = null;
2121
/* the number of threads */
2222
private int defaultNumOfThreads = 8;
2323
/* the minimum chunk size */
2424
private int minChunkSize = 512 * 1024; // 512K
2525
/* the downloader threads pool */
26-
private ThreadPuddle downloaderThreadsPool;
26+
private static ThreadPuddle downloaderThreadsPool;
2727
/* the factory of thread puddle class */
28-
private ThreadPuddleFactory threadPuddleFactory;
29-
/* final count of chunks */
30-
private int numOfChunks;
31-
/* completed task's ID so far */
32-
private int completedTaskID = -1;
33-
/* the start offset of the blob to be downloaded from */
34-
private int blobOffset;
35-
/* the length of bytes needed to be downloaded,
36-
* the length should be within a pre-defined range */
37-
private long length;
38-
/* the tasks list */
39-
private List<DownloadTask> downloadTasksList = new ArrayList<DownloadTask>();
28+
private static ThreadPuddleFactory threadPuddleFactory;
29+
4030

4131
/**
4232
* the task class of read/write operations
@@ -54,39 +44,55 @@ public DownloadTask(int taskID, int offset, long length) {
5444
}
5545
}
5646

47+
/**
48+
* constructor
49+
*/
50+
private ParallelDownloader(){
51+
initTheDownLoaderThreadsPool(this.defaultNumOfThreads);
52+
}
53+
54+
/**
55+
* get the singleton instance
56+
* @return
57+
*/
58+
public synchronized static ParallelDownloader getInstance () {
59+
if(instance == null){
60+
synchronized (ParallelDownloader.class) {
61+
if(instance == null){
62+
instance = new ParallelDownloader();
63+
}
64+
}
65+
}
66+
return instance;
67+
}
5768

5869
/**
5970
* initialize the threads pool
6071
*/
6172
private final void initTheDownLoaderThreadsPool(int numOfthreads){
6273
threadPuddleFactory = new ThreadPuddleFactory();
6374
threadPuddleFactory.setThreads(numOfthreads);
64-
threadPuddleFactory.setTaskLimit(numOfthreads);
6575
threadPuddleFactory.setFifo(true);
6676
downloaderThreadsPool = threadPuddleFactory.build();
6777
}
6878

69-
public ParallelDownloader(CloudBlob blob, int blobOffset, long length){
70-
this.blob = blob;
71-
this.blobOffset = blobOffset;
72-
this.length = length;
73-
getFinalNumOfChunks();
74-
initTheDownLoaderThreadsPool(numOfChunks);
75-
}
7679

77-
private void getFinalNumOfChunks(){
80+
private int getFinalNumOfChunks(long length){
7881
int tmpBlockCount = (int)((float)length / (float)minChunkSize) + 1;
7982
/* the final number of the chunks */
80-
numOfChunks = Math.min(defaultNumOfThreads, tmpBlockCount);
81-
return;
83+
int numOfChunks = Math.min(defaultNumOfThreads, tmpBlockCount);
84+
return numOfChunks;
8285
}
8386

8487
/**
8588
* generate the parallel tasks
8689
*/
87-
private final void splitJobIntoTheParallelTasks(){
90+
private final List<DownloadTask> splitJobIntoTheParallelTasks(int blobOffset, long length){
91+
List<DownloadTask> downloadTasksList = new ArrayList<DownloadTask>();
8892
int taskSequenceID = 0;
89-
int tmpOffset = this.blobOffset;
93+
int tmpOffset = blobOffset;
94+
/* get the number of chunks */
95+
int numOfChunks = getFinalNumOfChunks(length);
9096
/* the final size of the chunk */
9197
long numBtsInEachChunk = (long)(float)(length/numOfChunks);
9298
long bytesLeft = length;
@@ -109,15 +115,19 @@ private final void splitJobIntoTheParallelTasks(){
109115
/* increment/decrement counters */
110116
bytesLeft -= bytesToRead;
111117
}
112-
return;
118+
return downloadTasksList;
113119
}
114120

115-
public final byte[] downloadBlobWithParallelThreads() throws Exception{
121+
public final byte[] downloadBlobWithParallelThreads(final CloudBlob blob, final int blobOffset, final long length)
122+
throws Exception{
116123
final byte[] dlJobCentralBuffer = new byte[(int)length];
124+
/* completed task's ID so far */
125+
final int completedTaskID[] = new int[1];
126+
completedTaskID[0] = -1;
117127
final int failedTasks[] = new int[1];
118128
final int totalBtsDownloaded[] = new int[1];
119-
/* get the download tasks */
120-
splitJobIntoTheParallelTasks();
129+
/* generate the download tasks */
130+
List<DownloadTask> downloadTasksList = splitJobIntoTheParallelTasks(blobOffset,length);
121131
/* no tasks, return immediately */
122132
if (downloadTasksList.size() == 0){return dlJobCentralBuffer;}
123133
/* start the parallel reading */
@@ -137,7 +147,7 @@ public void run()
137147
/* check the downloaded result, break the loop if success*/
138148
if (bytesDownloaded == downloadTask.length) {
139149
/* wait for the pre-task to be completed */
140-
while(completedTaskID != downloadTask.taskID -1){
150+
while(completedTaskID[0] != downloadTask.taskID -1){
141151
Thread.sleep((Constants.DEFAULT_BFC_THREAD_SLEEP_MILLS/5));
142152
}
143153
/* get the offset in the central buffer */
@@ -148,7 +158,7 @@ public void run()
148158
/* update the total bytes downloaded */
149159
totalBtsDownloaded[0] += bytesDownloaded;
150160
/* update the offset of the completed task */
151-
completedTaskID = downloadTask.taskID;
161+
completedTaskID[0] = downloadTask.taskID;
152162
}
153163

154164

@@ -175,11 +185,11 @@ public void run()
175185
while(true){
176186
/* if there are any error, we should abandon this read operation */
177187
if (failedTasks[0] > 0){
178-
downloaderThreadsPool.die();
188+
//downloaderThreadsPool.die();
179189
throw new BfsException("read Failed:" + blob.getName());
180190
}
181191
/* completedTaskID start form 0 */
182-
if (downloadTasksList.size() == completedTaskID + 1 && totalBtsDownloaded[0] == length){
192+
if (downloadTasksList.size() == completedTaskID[0] + 1 && totalBtsDownloaded[0] == length){
183193
break;
184194
}
185195
Thread.sleep((Constants.DEFAULT_BFC_THREAD_SLEEP_MILLS/5));

0 commit comments

Comments
 (0)