Go 外部排序-网络版
目录结果

main.go
package main import (
"NetworkSort/pipeline"
"fmt"
"os"
"bufio"
) func main() {
const filename = "large.in"
const n = 100000000
file, err := os.Create(filename)
if err != nil {
panic(err)
}
defer file.Close()
p := pipeline.RandomSource(n)
writer := bufio.NewWriter(file)
pipeline.WriterSink(writer, p)
writer.Flush() file, err = os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
p = pipeline.ReaderSource(bufio.NewReader(file), -1)
count := 0
for v := range p {
fmt.Println(v)
count ++
if count >= 100 {
break
}
}
}
sort.go
package main import (
"os"
"NetworkSort/pipeline"
"bufio"
"fmt"
"strconv"
) func main() {
p := createNetworkPipeline("small.in", 512, 4)
writeToFile(p, "small.out")
printFile("small.out")
} func printFile(filename string) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
p := pipeline.ReaderSource(file, -1)
count := 0
for v:= range p {
fmt.Println(v)
count ++
if count >= 100 {
break
}
}
} func writeToFile(p <-chan int, filename string) {
file, err := os.Create(filename)
if err != nil {
panic(err)
}
defer file.Close()
writer := bufio.NewWriter(file)
defer writer.Flush()
pipeline.WriterSink(writer, p) } func createNetworkPipeline(filename string, fileSize, chunkCount int) <-chan int {
chunkSize := fileSize / chunkCount
pipeline.Init()
var sortAddr []string
for i := 0; i < chunkCount; i ++ {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
file.Seek(int64(i * chunkSize), 0)
source := pipeline.ReaderSource(bufio.NewReader(file), chunkSize)
addr := "127.0.0.1:" + strconv.Itoa(7000 + i)
fmt.Println("addr:", addr)
pipeline.NetworkSink(addr, pipeline.InMemorySort(source))
sortAddr = append(sortAddr, addr)
}
return nil
var sortResults []<-chan int
for _, addr := range sortAddr {
sortResults = append(sortResults, pipeline.NetworkSource(addr))
}
return pipeline.MergeN(sortResults ...)
}
nodes.go
package pipeline import (
"sort"
"io"
"encoding/binary"
"math/rand"
"time"
"fmt"
) var startTime time.Time func Init() {
startTime = time.Now()
} func ArraySource(a ...int) <-chan int {
out := make(chan int, 1024)
go func() {
for _, v := range a{
out <- v
}
close(out)
}()
return out
} func InMemorySort(in <-chan int) <-chan int {
out := make(chan int, 1024)
go func() {
// Read into memory
var a []int
for v := range in {
a = append(a, v)
}
fmt.Println("Read done:", time.Now().Sub(startTime))
// Sort
sort.Ints(a)
fmt.Println("InMemSort done:", time.Now().Sub(startTime)) // Output
for _, v := range a {
out <- v
}
close(out)
}()
return out
} func Merge(in1, in2 <-chan int) <-chan int {
out := make(chan int, 1024)
go func() {
v1, ok1 := <- in1
v2, ok2 := <- in2
for ok1 || ok2 {
if !ok2 || (ok1 && v1 <= v2) {
out <- v1
v1, ok1 = <-in1
} else {
out <- v2
v2, ok2 = <-in2
}
}
close(out)
fmt.Println("Merge done:", time.Now().Sub(startTime)) }()
return out
} func ReaderSource(reader io.Reader, chunkSize int) <-chan int {
out := make(chan int, 1024)
go func() {
buffer := make([]byte, 8)
bytesRead := 0
for {
n, err := reader.Read(buffer)
bytesRead += n
if n > 0 {
v := int(binary.BigEndian.Uint64(buffer))
out <- v
}
if err != nil || (chunkSize != -1 && bytesRead >= chunkSize){
break
}
}
close(out)
}()
return out
} func WriterSink(writer io.Writer, in <-chan int) {
for v := range in {
buffer := make([]byte, 8)
binary.BigEndian.PutUint64(buffer, uint64(v))
writer.Write(buffer)
}
} func RandomSource(count int) <-chan int {
out := make(chan int)
go func() {
for i:=0; i<count; i++ {
out <- rand.Int()
}
close(out)
}()
return out
} func MergeN(inputs ...<-chan int) <-chan int{
if len(inputs) == 1{
return inputs[0]
}
m := len(inputs) / 2 // merge inputs[0...m] and inputs[m...end]
return Merge(MergeN(inputs[:m] ...), MergeN(inputs[m:] ...))
}
network_nodes.go
package pipeline import (
"net"
"bufio"
) func NetworkSink(addr string, in <-chan int){
listener, err :=net.Listen("tcp", addr)
if err != nil {
panic(err)
}
go func() {
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
panic(err)
}
defer conn.Close()
writer := bufio.NewWriter(conn)
defer writer.Flush()
WriterSink(writer, in)
}()
} func NetworkSource(addr string) <-chan int {
out := make(chan int)
go func() {
conn, err := net.Dial("tcp", addr)
if err != nil {
panic(err)
}
r := ReaderSource(bufio.NewReader(conn), -1)
for v := range r {
out <- v
}
close(out)
}()
return out
}
Go 外部排序-网络版的更多相关文章
- sphinx 源码阅读之分词,压缩索引,倒排——单词对应的文档ID列表本质和lucene无异 也是外部排序再压缩 解压的时候需要全部扫描doc_ids列表偏移量相加获得最终的文档ID
转自:http://github.tiankonguse.com/blog/2014/12/03/sphinx-token-inverted-sort.html 外部排序 现在我们的背景是有16个已经 ...
- 外部排序&多路归并排序
外部排序: 一.定义问题 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序 整个文件的目的.外部排序最常 ...
- 大数据排序算法:外部排序,bitmap算法;大数据去重算法:hash算法,bitmap算法
外部排序算法相关:主要用到归并排序,堆排序,桶排序,重点是先分成不同的块,然后从每个块中找到最小值写入磁盘,分析过程可以看看http://blog.csdn.net/jeason29/article/ ...
- Go实现分布式外部排序
Go实现分布式外部排序 项目路径: https://github.com/Draymonders/go_external_sort 默认读入文件: small.in 默认输出文件:small.out ...
- Multithreading C++ Out of Core Sotring for Massive Data|多线程C++的大规模数据外部排序
先说一下,这个其实是我为实现PantaRay或者是类似Dreamworks的Out of Core点云GI的技术储备,为大规模点云光线跟踪所准备的第一步.在实际的应用中,int类型会被64bit的ui ...
- 常用算法——排序(一)
排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难.同样,存储在计算机中的数据的次序,对于处理这些数据的算法的 ...
- 八大排序算法Java
目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...
- 面试题目——《CC150》排序与查找
面试题11.1:给定两个排序后的数组A和B,其中A的末端有足够的缓冲空间容纳B.编写一个方法,将B合并入A并排序. package cc150.sort_search; public class Me ...
- [Data Structure & Algorithm] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
随机推荐
- C++实现文件关联
下面这段话是百度百科对文件关联的解释. 文件关联就是将一种类型的文件与一个可以打开它的程序建立起一种依存关系.举个例子来说,位图文件(BMP文件)在Windows中的默认关联程序是“画图”,如果将其默 ...
- ios 集成阿里百川的坑-【SDK初始化-iOS】读取身份图片AppKey失败
最简易方法调用淘宝app: 引用文件 #import <AlibcTradeSDK/AlibcTradeSDK.h> AlibcWebViewController* view = [[Al ...
- Android无线测试之—UiAutomator UiDevice API介绍六
一.灭屏和唤醒屏幕相关知识: 1)灭屏:按电源键将屏幕熄灭 2)唤醒屏幕:在灭屏状态下按电源键唤醒屏幕 二.灭屏与唤屏相关的API: 返回值 方法名 描述 void wakeUp() 模拟按电源键,如 ...
- 山石防火墙debug
debug dp basic debug dp snoop debup dp drop debug dp filter src-ip ? show logging debug
- 《从零开始学Swift》学习笔记(Day 26)——可选链
原创文章,欢迎转载.转载请注明:关东升的博客 在Swift程序表达式中会看到问号(?)和感叹号(!),它们代表什么含义呢?这些符号都与可选类型和可选链相关,下面来看看可选链. 可选链: 类图: 它们之 ...
- C#访问修饰符比较
- 字符串 转 时间戳 unix_timestamp('2018-07-01 0:0:0')
SELECT FROM_UNIXTIME(createtime,'%Y%m%d') AS d, s.app,SUM(o.val) FROM orders o LEFT JOIN app_type s ...
- setlocale()函数测试当前语言的两个程序
http://www.cnblogs.com/cnyao/archive/2010/05/06/1729220.html setlocale()函数是用来配置地域信息的,原本以为这个也是windows ...
- 前端基础 & Bootstrap框架
Bootstrap介绍 Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架. 它是为实现快速开发Web应用程序而设计的一套前端工具包. 它支持响应式布局,并且 ...
- Js算两经纬度间球面距离
function GetDistance( lat1, lng1, lat2, lng2){ var radLat1 = lat1 * Math.PI / 180.0 var radLat2 = la ...