yaokai1117tiny up3e609ba11 years agoHistory
398 lines · 9.1 KB · Brainfuck
RawDownload
##########################################	The implemention of DFSClient.#	It creates some connections with DFSServer and DFSNodeServer,#	and communicate information and data with them.#	#	@author Kai Yao(yaokai)#	@author Yang Fan(fyabc) ######################################### implement DFSClient; include "sys.m";include "dfsutil.m";include "dfsclient.m"; include "../xml/xmlhandle.m";include "xml.m";include "bufio.m";include "lists.m"; sys : Sys;dfsutil : DFSUtil; xml : Xml;xmlhd : XmlHandle;bufio : Bufio;lists : Lists; DFSFile : import dfsutil;DFSChunk : import dfsutil;DFSNode : import dfsutil;Connection : import sys;Parser : import xml;FD : import sys;Iobuf : import bufio; masterAddr : string;masterPort : int;defaultRep : int;defaultChunkSize : int;defaultTempPath : string; conn : Connection;init() { 	if (sys == nil)		sys = load Sys Sys->PATH;	if (dfsutil == nil)		dfsutil = load DFSUtil DFSUtil->PATH;	if (xml == nil)		xml = load Xml Xml->PATH;	if (xmlhd == nil)		xmlhd = load XmlHandle XmlHandle->PATH;	if (lists == nil)		lists = load Lists Lists->PATH;	if (bufio == nil)		bufio = load Bufio Bufio->PATH; 	xml->init();	dfsutil->init(); 	#masterAddr = "192.168.43.216";	#masterPort = 2333; 	buffer := bufio->open("/appl/MR/config", Bufio->OREAD);	masterAddr = buffer.gets('\n');	masterAddr = masterAddr[:len masterAddr - 1];	masterPort = 2333; 	defaultRep = 3;	defaultChunkSize = 1<<20;	defaultTempPath = "/appl/MR/cli/"; 	ok : int;	(ok, conn) = sys->dial("tcp!" + masterAddr + "!" + string masterPort, nil);	if (ok < 0) 		sys->print("Error: DFSClient--dial failed!\n");} disconnect(){	sys->fprint(conn.dfd, "disconnect");} createFile(fileName : string, replicas : int) : int {	buf := array [Sys->ATOMICIO] of byte;	msg := "create@" + fileName + "@" + string replicas; 	sys->fprint(conn.dfd, "%s", msg);	length := sys->read(conn.dfd, buf, len buf);	if (length <= 0) {		sys->print("Error: DFSClient--createFile failed!\n");			return 1;	}	sys->print("%s", string buf[:length]);	return 0;} createChunk(fileName : string, offset : big, size : int) : int{	buf := array [Sys->ATOMICIO] of byte;	msg := "chunk@" + fileName + "@" + string offset + "@" + string size;	sys->fprint(conn.dfd, "%s", msg);	length := sys->read(conn.dfd, buf, len buf);	ok := int string buf[:length];	if (ok != 0) {		sys->print("Error: DFSClient--createChunk failed: %d !,offset: %bd, size: %d\n", ok, offset, size);		return 1;	}	return 0;} listFiles() : string{	buf := array [Sys->ATOMICIO] of byte;	msg := "list";	sys->fprint(conn.dfd, "%s", msg);	length := sys->read(conn.dfd, buf, len buf);	if (length <= 0)		return nil;	ret := string buf[:length];	return ret;} getFile(fileName : string) : ref DFSFile{	buf := array [Sys->ATOMICIO] of byte;	msg := "get@" + fileName;	sys->fprint(conn.dfd, "%s", msg); 	length := sys->read(conn.dfd, buf, len buf);	if (length <= 0) {		sys->print("Error: DFSClient--deleteFile failed!\n");			return nil;	}	sys->print("%s", string buf[:length]);	if (int buf[0] == 'N')		return nil; 	sys->fprint(conn.dfd, "start");	sys->export(conn.dfd, defaultTempPath, Sys->EXPWAIT);		parser := xmlhd->init(defaultTempPath + fileName + ".xml");	file := xmlhd->xml2file(parser);	sys->remove(defaultTempPath + fileName + ".xml");	return file;} deleteFile(fileName : string) : int{	buf := array [Sys->ATOMICIO] of byte;	msg := "delete@" + fileName;	sys->fprint(conn.dfd, "%s", msg);		length := sys->read(conn.dfd, buf, len buf);	if (length <= 0) {		sys->print("Error: DFSClient--deleteFile failed!\n");			return 1;	}	sys->print("%s", string buf[:length]);	if (int buf[0] == 'N')		return 1; 	return 0;} updateNode(addr : string, port : int, chunkNumber : int) : int{	buf := array [Sys->ATOMICIO] of byte;	msg := "upNode@" + addr + "@" + string port + "@" +  string chunkNumber; 	sys->fprint(conn.dfd, "%s", msg);	length := sys->read(conn.dfd, buf, len buf);	if (length <= 0) {		sys->print("Error: DFSClient--updateNode failed!\n");			return 1;	}	sys->print("%s", string buf[:length]);	return 0;} removeNode(addr : string, port : int) : int{	buf := array [Sys->ATOMICIO] of byte;	msg := "rmNode@" + addr + "@" + string port; 	sys->fprint(conn.dfd, "%s", msg); 	length := sys->read(conn.dfd, buf, len buf);	if (length <= 0) {		sys->print("Error: DFSClient--removeNode failed!\n");			return 1;	}	sys->print("%s", string buf[:length]);	if (int buf[0] == 'N')		return 1; 	return 0;} # fyabc readChunk(chunk : ref DFSChunk) : ref FD{	node : ref DFSNode; 	for(p := chunk.nodes; p != nil; p = tl p)	{		node = hd p;		if((ret := readChunkWithNode(node, chunk.id)) != nil)			return ret;	}		sys->print("All nodes of this chunk %d are failed to read!", chunk.id);	return nil;} writeChunk(chunk : ref DFSChunk, offset : big, size : int, datafd : ref FD) : int{	ret := 0;	node : ref DFSNode; 	for(p := chunk.nodes; p != nil; p = tl p)	{		sys->seek(datafd, offset, Sys->SEEKSTART);		node = hd p;		if(writeChunkWithNode(node, chunk.id, size, datafd) != 0)		{			sys->print("Write chunk %d in node addr: %s, port: %d failed!\n", chunk.id, node.addr, node.port);			ret = -1;		}		else			sys->print("Successed write chunk %d in node addr: %s, port: %d!\n", chunk.id, node.addr, node.port);	}        return ret;} deleteChunk(chunk : ref DFSChunk) : int{	ret := 0;	node : ref DFSNode;	for(p := chunk.nodes; p != nil; p = tl p)	{		node = hd p;		if(deleteChunkWithNode(node, chunk.id)!=0)		{			sys->print("Delete chunk %d in node addr: %s, port: %d failed!\n", chunk.id, node.addr, node.port);			ret = -1;		}		else		sys->print("Successed delete chunk %d in node addr: %s, port: %d!\n", chunk.id, node.addr, node.port);    }        return ret;} lineOffset(fileName : string) : array of big{	file := getFile(fileName);	offsets : list of big; 	chunk : ref DFSChunk;	for(p := file.chunks; p != nil; p = tl p)	{		chunk = hd p;		chunkOffsets := lineOffsetChunk(chunk); 		for(i := 0; i < len chunkOffsets; i++)		{			offsets = chunkOffsets[i] :: offsets;		}	} 	length := len offsets;	ret := array[length] of big;	for(j := length-1; j>=0; j--)	{		ret[j] = hd offsets;		offsets = tl offsets;	}	return ret;} lineOffsetChunk(chunk : ref DFSChunk) : array of big{	node : ref DFSNode; 	for(p := chunk.nodes; p != nil; p = tl p)	{		node = hd p;		(ok, conn) := sys->dial("tcp!" + node.addr + "!" + string node.port, nil);		if (ok >= 0)		{			msg := "lineos@" + string chunk.id;			sys->fprint(conn.dfd, "%s", msg); 			buf := array [Sys->ATOMICIO] of byte;			length := sys->read(conn.dfd, buf, len buf);			(nil,chunkOffsets) := sys->tokenize(string buf[:length], " ") ;			sys->print("%d\n",len chunkOffsets);			ret := array[len chunkOffsets] of big; 			for(i :=0; i< len ret; i++)			{				ret[i] = big (hd chunkOffsets) + chunk.offset;				chunkOffsets = tl chunkOffsets;			} 			return ret;		}	} 	sys->print("All nodes of this chunk %d are failed to lineOffset!", chunk.id);	return nil;} readChunkWithNode(node : ref DFSNode, chunkId : int) : ref FD{	ok : int;	(ok, conn) = sys->dial("tcp!" + node.addr + "!" + string node.port, nil);	if (ok < 0)	{		sys->print("Error: DFSClient->readChunk--dial failed!\n");		return nil;	} 	buf := array [Sys->ATOMICIO] of byte;	msg := "read@" + string chunkId;	sys->fprint(conn.dfd, "%s", msg); 	sys->export(conn.dfd, defaultTempPath, Sys->EXPWAIT); 	ret := sys->open(defaultTempPath + string chunkId, sys->ORDWR); 	return ret;} writeChunkWithNode(node : ref DFSNode, chunkId : int, size : int, datafd : ref FD) : int{	ok : int;	(ok, conn) = sys->dial("tcp!" + node.addr + "!" + string node.port, nil);	if (ok < 0)	{		sys->print("Error: DFSClient->writeChunk--dial failed!\n");		return -1;	} 	buf := array [Sys->ATOMICIO] of byte;	msg := "write" ;	sys->fprint(conn.dfd, "%s", msg); 	sendWriteData(datafd, chunkId, size, conn); 	return 0; } deleteChunkWithNode(node : ref DFSNode, chunkId : int) : int{	ok : int;	(ok, conn) = sys->dial("tcp!" + node.addr + "!" + string node.port, nil);	if (ok < 0)	{		sys->print("Error: DFSClient->writeChunk--dial failed!\n");		return -1;	}		buf := array [Sys->ATOMICIO] of byte;	msg := "delete@" + string chunkId;	sys->fprint(conn.dfd, "%s", msg); 	length := sys->read(conn.dfd, buf, len buf);	return int string buf[:length];	} sendWriteData(datafd : ref FD, chunkId : int, size : int, conn : Connection){	stmsg := array[100] of byte;	n := sys->read(conn.dfd, stmsg, len stmsg);	sys->mount(conn.dfd, nil, defaultTempPath + "remote",Sys->MCREATE, nil);	datacopyfd := sys->create(defaultTempPath + "remote/" + string chunkId, sys->ORDWR, 8r600); 	buf := array [Sys->ATOMICIO] of byte;	length : int;	(nil, dir) := sys->fstat(datafd);	total := dir.length;	offset := sys->seek(datafd, big 0, Sys->SEEKRELA);	if (int(total - offset) < size)		size = int(total - offset);	do {		if (size < len buf) 			length = sys->read(datafd, buf, size);		else			length = sys->read(datafd, buf, len buf);		sys->write(datacopyfd, buf[:length], length);		size -= length; 	}while (size > 0); 	sys->unmount(nil, defaultTempPath + "remote");}